1. Project Clover database Tue Apr 9 2024 16:11:52 CDT
  2. Package com.alibaba.fastjson.util

File TypeUtils.java

 
test_date: parseLong error, field : value
 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
23% of files have more coverage

Code metrics

1,072
1,679
95
1
3,145
2,794
833
0.5
17.67
95
8.77

Classes

Class Line # Actions
TypeUtils 60 1,679 0% 833 320
0.887561588.8%
 

Contributing tests

This file is covered by 2601 tests. .

Source view

1    /*
2    * Copyright 1999-2017 Alibaba Group.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package com.alibaba.fastjson.util;
17   
18    import com.alibaba.fastjson.JSON;
19    import com.alibaba.fastjson.JSONException;
20    import com.alibaba.fastjson.JSONObject;
21    import com.alibaba.fastjson.PropertyNamingStrategy;
22    import com.alibaba.fastjson.annotation.JSONField;
23    import com.alibaba.fastjson.annotation.JSONType;
24    import com.alibaba.fastjson.parser.DefaultJSONParser;
25    import com.alibaba.fastjson.parser.Feature;
26    import com.alibaba.fastjson.parser.JSONScanner;
27    import com.alibaba.fastjson.parser.ParserConfig;
28    import com.alibaba.fastjson.parser.deserializer.EnumDeserializer;
29    import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
30    import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
31    import com.alibaba.fastjson.serializer.CalendarCodec;
32    import com.alibaba.fastjson.serializer.SerializeBeanInfo;
33    import com.alibaba.fastjson.serializer.SerializerFeature;
34   
35    import java.lang.annotation.Annotation;
36    import java.lang.reflect.AccessibleObject;
37    import java.lang.reflect.Array;
38    import java.lang.reflect.Constructor;
39    import java.lang.reflect.Field;
40    import java.lang.reflect.GenericArrayType;
41    import java.lang.reflect.Method;
42    import java.lang.reflect.Modifier;
43    import java.lang.reflect.ParameterizedType;
44    import java.lang.reflect.Proxy;
45    import java.lang.reflect.Type;
46    import java.lang.reflect.TypeVariable;
47    import java.lang.reflect.WildcardType;
48    import java.math.BigDecimal;
49    import java.math.BigInteger;
50    import java.security.AccessControlException;
51    import java.text.ParseException;
52    import java.text.SimpleDateFormat;
53    import java.util.*;
54    import java.util.concurrent.ConcurrentHashMap;
55    import java.util.concurrent.ConcurrentMap;
56   
57    /**
58    * @author wenshao[szujobs@hotmail.com]
59    */
 
60    public class TypeUtils{
61   
62    public static boolean compatibleWithJavaBean = false;
63    /** 根据field name的大小写输出输入数据 */
64    public static boolean compatibleWithFieldName = false;
65    private static boolean setAccessibleEnable = true;
66    private static boolean oracleTimestampMethodInited = false;
67    private static Method oracleTimestampMethod;
68    private static boolean oracleDateMethodInited = false;
69    private static Method oracleDateMethod;
70    private static boolean optionalClassInited = false;
71    private static Class<?> optionalClass;
72    private static boolean transientClassInited = false;
73    private static Class<? extends Annotation> transientClass;
74   
75    private static Class<? extends Annotation> class_OneToMany = null;
76    private static boolean class_OneToMany_error = false;
77    private static Class<? extends Annotation> class_ManyToMany = null;
78    private static boolean class_ManyToMany_error = false;
79   
80    private static Method method_HibernateIsInitialized = null;
81    private static boolean method_HibernateIsInitialized_error = false;
82    private static volatile Class kotlin_metadata;
83    private static volatile boolean kotlin_metadata_error;
84    private static volatile boolean kotlin_class_klass_error;
85    private static volatile Constructor kotlin_kclass_constructor;
86    private static volatile Method kotlin_kclass_getConstructors;
87    private static volatile Method kotlin_kfunction_getParameters;
88    private static volatile Method kotlin_kparameter_getName;
89    private static volatile boolean kotlin_error;
90    private static volatile Map<Class,String[]> kotlinIgnores;
91    private static volatile boolean kotlinIgnores_error;
92    private static ConcurrentMap<String,Class<?>> mappings = new ConcurrentHashMap<String,Class<?>>(256, 0.75f, 1);
93    private static Class<?> pathClass;
94    private static boolean pathClass_error = false;
95   
96    private static Class<? extends Annotation> class_JacksonCreator = null;
97    private static boolean class_JacksonCreator_error = false;
98   
99    private static volatile Class class_Clob = null;
100    private static volatile boolean class_Clob_error = false;
101   
102    private static volatile Class class_XmlAccessType = null;
103    private static volatile Class class_XmlAccessorType = null;
104    private static volatile boolean classXmlAccessorType_error = false;
105    private static volatile Method method_XmlAccessorType_value = null;
106    private static volatile Field field_XmlAccessType_FIELD = null;
107    private static volatile Object field_XmlAccessType_FIELD_VALUE = null;
108   
 
109  1 toggle static{
110  1 try{
111  1 TypeUtils.compatibleWithJavaBean = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHJAVABEAN));
112  1 TypeUtils.compatibleWithFieldName = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHFIELDNAME));
113    } catch(Throwable e){
114    // skip
115    }
116    }
117   
 
118  1 toggle static{
119  1 addBaseClassMappings();
120    }
121   
122   
 
123  1194 toggle public static boolean isXmlField(Class clazz) {
124  1194 if (class_XmlAccessorType == null && !classXmlAccessorType_error) {
125  1 try {
126  1 class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType");
127    } catch(Throwable ex){
128  0 classXmlAccessorType_error = true;
129    }
130    }
131   
132  1194 if (class_XmlAccessorType == null) {
133  0 return false;
134    }
135   
136  1194 Annotation annotation = TypeUtils.getAnnotation(clazz, class_XmlAccessorType);
137  1194 if (annotation == null) {
138  1191 return false;
139    }
140   
141  3 if (method_XmlAccessorType_value == null && !classXmlAccessorType_error) {
142  1 try {
143  1 method_XmlAccessorType_value = class_XmlAccessorType.getMethod("value");
144    } catch(Throwable ex){
145  0 classXmlAccessorType_error = true;
146    }
147    }
148   
149  3 if (method_XmlAccessorType_value == null) {
150  0 return false;
151    }
152   
153  3 Object value = null;
154  3 if (!classXmlAccessorType_error) {
155  3 try {
156  3 value = method_XmlAccessorType_value.invoke(annotation);
157    } catch (Throwable ex) {
158  0 classXmlAccessorType_error = true;
159    }
160    }
161  3 if (value == null) {
162  0 return false;
163    }
164   
165  3 if (class_XmlAccessType == null && !classXmlAccessorType_error) {
166  1 try {
167  1 class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType");
168  1 field_XmlAccessType_FIELD = class_XmlAccessType.getField("FIELD");
169  1 field_XmlAccessType_FIELD_VALUE = field_XmlAccessType_FIELD.get(null);
170    } catch(Throwable ex){
171  0 classXmlAccessorType_error = true;
172    }
173    }
174   
175  3 return value == field_XmlAccessType_FIELD_VALUE;
176    }
177   
 
178  0 toggle public static Annotation getXmlAccessorType(Class clazz) {
179  0 if (class_XmlAccessorType == null && !classXmlAccessorType_error) {
180   
181  0 try{
182  0 class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType");
183    } catch(Throwable ex){
184  0 classXmlAccessorType_error = true;
185    }
186    }
187   
188  0 if (class_XmlAccessorType == null) {
189  0 return null;
190    }
191   
192  0 return TypeUtils.getAnnotation(clazz, class_XmlAccessorType);
193    }
194   
195    //
196    // public static boolean isXmlAccessType(Class clazz) {
197    // if (class_XmlAccessType == null && !class_XmlAccessType_error) {
198    //
199    // try{
200    // class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType");
201    // } catch(Throwable ex){
202    // class_XmlAccessType_error = true;
203    // }
204    // }
205    //
206    // if (class_XmlAccessType == null) {
207    // return false;
208    // }
209    //
210    // return class_XmlAccessType.isAssignableFrom(clazz);
211    // }
212   
 
213  1617 toggle public static boolean isClob(Class clazz) {
214  1618 if (class_Clob == null && !class_Clob_error) {
215   
216  1 try{
217  1 class_Clob = Class.forName("java.sql.Clob");
218    } catch(Throwable ex){
219  0 class_Clob_error = true;
220    }
221    }
222   
223  1619 if (class_Clob == null) {
224  0 return false;
225    }
226   
227  1618 return class_Clob.isAssignableFrom(clazz);
228    }
229   
 
230  57 toggle public static String castToString(Object value){
231  57 if(value == null){
232  2 return null;
233    }
234  55 return value.toString();
235    }
236   
 
237  30 toggle public static Byte castToByte(Object value){
238  30 if(value == null){
239  4 return null;
240    }
241   
242  26 if(value instanceof BigDecimal){
243  0 return byteValue((BigDecimal) value);
244    }
245   
246  26 if(value instanceof Number){
247  13 return ((Number) value).byteValue();
248    }
249   
250  13 if(value instanceof String){
251  10 String strVal = (String) value;
252  10 if(strVal.length() == 0 //
253    || "null".equals(strVal) //
254    || "NULL".equals(strVal)){
255  4 return null;
256    }
257  6 return Byte.parseByte(strVal);
258    }
259  3 throw new JSONException("can not cast to byte, value : " + value);
260    }
261   
 
262  19 toggle public static Character castToChar(Object value){
263  19 if(value == null){
264  1 return null;
265    }
266  18 if(value instanceof Character){
267  1 return (Character) value;
268    }
269  17 if(value instanceof String){
270  16 String strVal = (String) value;
271  16 if(strVal.length() == 0){
272  2 return null;
273    }
274  14 if(strVal.length() != 1){
275  1 throw new JSONException("can not cast to char, value : " + value);
276    }
277  13 return strVal.charAt(0);
278    }
279  1 throw new JSONException("can not cast to char, value : " + value);
280    }
281   
 
282  155 toggle public static Short castToShort(Object value){
283  155 if(value == null){
284  4 return null;
285    }
286   
287  151 if(value instanceof BigDecimal){
288  0 return shortValue((BigDecimal) value);
289    }
290   
291  151 if(value instanceof Number){
292  138 return ((Number) value).shortValue();
293    }
294   
295  13 if(value instanceof String){
296  10 String strVal = (String) value;
297  10 if(strVal.length() == 0 //
298    || "null".equals(strVal) //
299    || "NULL".equals(strVal)){
300  4 return null;
301    }
302  6 return Short.parseShort(strVal);
303    }
304   
305  3 throw new JSONException("can not cast to short, value : " + value);
306    }
307   
 
308  22 toggle public static BigDecimal castToBigDecimal(Object value){
309  22 if(value == null){
310  2 return null;
311    }
312  20 if(value instanceof BigDecimal){
313  1 return (BigDecimal) value;
314    }
315  19 if(value instanceof BigInteger){
316  1 return new BigDecimal((BigInteger) value);
317    }
318  18 String strVal = value.toString();
319  18 if(strVal.length() == 0){
320  1 return null;
321    }
322  17 if(value instanceof Map && ((Map) value).size() == 0){
323  1 return null;
324    }
325  16 return new BigDecimal(strVal);
326    }
327   
 
328  18 toggle public static BigInteger castToBigInteger(Object value){
329  18 if(value == null){
330  2 return null;
331    }
332  16 if(value instanceof BigInteger){
333  1 return (BigInteger) value;
334    }
335  15 if(value instanceof Float || value instanceof Double){
336  6 return BigInteger.valueOf(((Number) value).longValue());
337    }
338  9 if(value instanceof BigDecimal){
339  0 BigDecimal decimal = (BigDecimal) value;
340  0 int scale = decimal.scale();
341  0 if (scale > -1000 && scale < 1000) {
342  0 return ((BigDecimal) value).toBigInteger();
343    }
344    }
345  9 String strVal = value.toString();
346  9 if(strVal.length() == 0 //
347    || "null".equals(strVal) //
348    || "NULL".equals(strVal)){
349  2 return null;
350    }
351  7 return new BigInteger(strVal);
352    }
353   
 
354  12000162 toggle public static Float castToFloat(Object value){
355  12000162 if(value == null){
356  4 return null;
357    }
358  12000158 if(value instanceof Number){
359  12000144 return ((Number) value).floatValue();
360    }
361  14 if(value instanceof String){
362  11 String strVal = value.toString();
363  11 if(strVal.length() == 0 //
364    || "null".equals(strVal) //
365    || "NULL".equals(strVal)){
366  5 return null;
367    }
368  6 if(strVal.indexOf(',') != 0){
369  6 strVal = strVal.replaceAll(",", "");
370    }
371  6 return Float.parseFloat(strVal);
372    }
373  3 throw new JSONException("can not cast to float, value : " + value);
374    }
375   
 
376  2000167 toggle public static Double castToDouble(Object value){
377  2000167 if(value == null){
378  5 return null;
379    }
380  2000162 if(value instanceof Number){
381  2000147 return ((Number) value).doubleValue();
382    }
383  15 if(value instanceof String){
384  12 String strVal = value.toString();
385  12 if(strVal.length() == 0 //
386    || "null".equals(strVal) //
387    || "NULL".equals(strVal)){
388  6 return null;
389    }
390  6 if(strVal.indexOf(',') != 0){
391  6 strVal = strVal.replaceAll(",", "");
392    }
393  6 return Double.parseDouble(strVal);
394    }
395  3 throw new JSONException("can not cast to double, value : " + value);
396    }
397   
 
398  2078 toggle public static Date castToDate(Object value){
399  2078 Test failure here return castToDate(value, null);
400    }
401   
 
402  2082 toggle public static Date castToDate(Object value, String format){
403  2082 if(value == null){
404  2 return null;
405    }
406   
407  2080 if(value instanceof Date){ // 使用频率最高的,应优先处理
408  4 return (Date) value;
409    }
410   
411  2076 if(value instanceof Calendar){
412  1 return ((Calendar) value).getTime();
413    }
414   
415  2075 long longValue = -1;
416   
417  2075 if(value instanceof BigDecimal){
418  0 longValue = longValue((BigDecimal) value);
419  0 return new Date(longValue);
420    }
421   
422  2075 if(value instanceof Number){
423  2049 longValue = ((Number) value).longValue();
424  2049 if ("unixtime".equals(format)) {
425  2 longValue *= 1000;
426    }
427  2049 return new Date(longValue);
428    }
429   
430  26 if(value instanceof String){
431  23 String strVal = (String) value;
432  23 JSONScanner dateLexer = new JSONScanner(strVal);
433  23 try{
434  23 if(dateLexer.scanISO8601DateIfMatch(false)){
435  10 Calendar calendar = dateLexer.getCalendar();
436  10 return calendar.getTime();
437    }
438    } finally{
439  23 dateLexer.close();
440    }
441   
442  13 if (strVal.startsWith("/Date(") && strVal.endsWith(")/")) {
443  1 strVal = strVal.substring(6, strVal.length() - 2);
444    }
445   
446  13 if (strVal.indexOf('-') > 0 || strVal.indexOf('+') > 0) {
447  6 if (format == null) {
448  3 if (strVal.length() == JSON.DEFFAULT_DATE_FORMAT.length()
449    || (strVal.length() == 22 && JSON.DEFFAULT_DATE_FORMAT.equals("yyyyMMddHHmmssSSSZ"))) {
450  0 format = JSON.DEFFAULT_DATE_FORMAT;
451  3 } else if (strVal.length() == 10) {
452  1 format = "yyyy-MM-dd";
453  1 } else if (strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) {
454  0 format = "yyyy-MM-dd HH:mm:ss";
455  1 } else if (strVal.length() == 29
456    && strVal.charAt(26) == ':'
457    && strVal.charAt(28) == '0') {
458  0 format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
459  1 } else if (strVal.length() == 23 && strVal.charAt(19) == ',') {
460  1 format = "yyyy-MM-dd HH:mm:ss,SSS";
461    } else {
462  0 format = "yyyy-MM-dd HH:mm:ss.SSS";
463    }
464    }
465   
466  6 Test failure here SimpleDateFormat dateFormat = new SimpleDateFormat(format, JSON.defaultLocale);
467  5 dateFormat.setTimeZone(JSON.defaultTimeZone);
468  5 try{
469  5 return dateFormat.parse(strVal);
470    } catch(ParseException e){
471  1 throw new JSONException("can not cast to Date, value : " + strVal);
472    }
473    }
474  7 if(strVal.length() == 0){
475  2 return null;
476    }
477  5 longValue = Long.parseLong(strVal);
478    }
479   
480  7 if (longValue == -1) {
481  3 Class<?> clazz = value.getClass();
482  3 if("oracle.sql.TIMESTAMP".equals(clazz.getName())){
483  1 if(oracleTimestampMethod == null && !oracleTimestampMethodInited){
484  1 try{
485  1 oracleTimestampMethod = clazz.getMethod("toJdbc");
486    } catch(NoSuchMethodException e){
487    // skip
488    } finally{
489  1 oracleTimestampMethodInited = true;
490    }
491    }
492  1 Object result;
493  1 try{
494  1 result = oracleTimestampMethod.invoke(value);
495    } catch(Exception e){
496  0 throw new JSONException("can not cast oracle.sql.TIMESTAMP to Date", e);
497    }
498  1 return (Date) result;
499    }
500  2 if("oracle.sql.DATE".equals(clazz.getName())){
501  1 if(oracleDateMethod == null && !oracleDateMethodInited){
502  1 try{
503  1 oracleDateMethod = clazz.getMethod("toJdbc");
504    } catch(NoSuchMethodException e){
505    // skip
506    } finally{
507  1 oracleDateMethodInited = true;
508    }
509    }
510  1 Object result;
511  1 try{
512  1 result = oracleDateMethod.invoke(value);
513    } catch(Exception e){
514  0 throw new JSONException("can not cast oracle.sql.DATE to Date", e);
515    }
516  1 return (Date) result;
517    }
518   
519  1 throw new JSONException("can not cast to Date, value : " + value);
520    }
521   
522  4 return new Date(longValue);
523    }
524   
 
525  12 toggle public static java.sql.Date castToSqlDate(Object value){
526  12 if(value == null){
527  2 return null;
528    }
529  10 if(value instanceof java.sql.Date){
530  1 return (java.sql.Date) value;
531    }
532  9 if(value instanceof java.util.Date){
533  1 return new java.sql.Date(((java.util.Date) value).getTime());
534    }
535  8 if(value instanceof Calendar){
536  1 return new java.sql.Date(((Calendar) value).getTimeInMillis());
537    }
538   
539  7 long longValue = 0;
540  7 if(value instanceof BigDecimal){
541  0 longValue = longValue((BigDecimal) value);
542  7 } else if(value instanceof Number){
543  5 longValue = ((Number) value).longValue();
544    }
545   
546  7 if(value instanceof String){
547  2 String strVal = (String) value;
548  2 if(strVal.length() == 0 //
549    || "null".equals(strVal) //
550    || "NULL".equals(strVal)){
551  1 return null;
552    }
553  1 if(isNumber(strVal)){
554  1 longValue = Long.parseLong(strVal);
555    } else{
556  0 JSONScanner scanner = new JSONScanner(strVal);
557  0 if(scanner.scanISO8601DateIfMatch(false)){
558  0 longValue = scanner.getCalendar().getTime().getTime();
559    } else{
560  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
561    }
562    }
563    }
564  6 if(longValue <= 0){
565  1 throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理?
566    }
567  5 return new java.sql.Date(longValue);
568    }
569   
 
570  147 toggle public static long longExtractValue(Number number) {
571  147 if (number instanceof BigDecimal) {
572  11 return ((BigDecimal) number).longValueExact();
573    }
574   
575  136 return number.longValue();
576    }
577   
 
578  2 toggle public static java.sql.Time castToSqlTime(Object value){
579  2 if(value == null){
580  0 return null;
581    }
582  2 if(value instanceof java.sql.Time){
583  0 return (java.sql.Time) value;
584    }
585  2 if(value instanceof java.util.Date){
586  0 return new java.sql.Time(((java.util.Date) value).getTime());
587    }
588  2 if(value instanceof Calendar){
589  0 return new java.sql.Time(((Calendar) value).getTimeInMillis());
590    }
591   
592  2 long longValue = 0;
593  2 if(value instanceof BigDecimal){
594  0 longValue = longValue((BigDecimal) value);
595  2 } else if(value instanceof Number){
596  2 longValue = ((Number) value).longValue();
597    }
598   
599  2 if(value instanceof String){
600  0 String strVal = (String) value;
601  0 if(strVal.length() == 0 //
602    || "null".equalsIgnoreCase(strVal)){
603  0 return null;
604    }
605  0 if(isNumber(strVal)){
606  0 longValue = Long.parseLong(strVal);
607    } else{
608  0 JSONScanner scanner = new JSONScanner(strVal);
609  0 if(scanner.scanISO8601DateIfMatch(false)){
610  0 longValue = scanner.getCalendar().getTime().getTime();
611    } else{
612  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
613    }
614    }
615    }
616  2 if(longValue <= 0){
617  0 throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理?
618    }
619  2 return new java.sql.Time(longValue);
620    }
621   
 
622  21 toggle public static java.sql.Timestamp castToTimestamp(Object value){
623  21 if(value == null){
624  2 return null;
625    }
626  19 if(value instanceof Calendar){
627  1 return new java.sql.Timestamp(((Calendar) value).getTimeInMillis());
628    }
629  18 if(value instanceof java.sql.Timestamp){
630  1 return (java.sql.Timestamp) value;
631    }
632  17 if(value instanceof java.util.Date){
633  2 return new java.sql.Timestamp(((java.util.Date) value).getTime());
634    }
635  15 long longValue = 0;
636  15 if(value instanceof BigDecimal){
637  1 longValue = longValue((BigDecimal) value);
638  14 } else if(value instanceof Number){
639  7 longValue = ((Number) value).longValue();
640    }
641  15 if(value instanceof String){
642  7 String strVal = (String) value;
643  7 if(strVal.length() == 0 //
644    || "null".equals(strVal) //
645    || "NULL".equals(strVal)){
646  1 return null;
647    }
648  5 if(strVal.endsWith(".000000000")){
649  0 strVal = strVal.substring(0, strVal.length() - 10);
650  4 } else if(strVal.endsWith(".000000")){
651  0 strVal = strVal.substring(0, strVal.length() - 7);
652    }
653  1 if(isNumber(strVal)){
654  1 longValue = Long.parseLong(strVal);
655    } else{
656  0 JSONScanner scanner = new JSONScanner(strVal);
657  0 if(scanner.scanISO8601DateIfMatch(false)){
658  0 longValue = scanner.getCalendar().getTime().getTime();
659    } else{
660  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
661    }
662    }
663    }
664  9 if(longValue <= 0){
665  1 throw new JSONException("can not cast to Timestamp, value : " + value);
666    }
667  8 return new java.sql.Timestamp(longValue);
668    }
669   
 
670  72 toggle public static boolean isNumber(String str){
671  210 for(int i = 0; i < str.length(); ++i){
672  149 char ch = str.charAt(i);
673  149 if(ch == '+' || ch == '-'){
674  3 if(i != 0){
675  0 return false;
676    }
677  141 } else if(ch < '0' || ch > '9'){
678  6 return false;
679    }
680    }
681  61 return true;
682    }
683   
 
684  4386 toggle public static Long castToLong(Object value){
685  4386 if(value == null){
686  25 return null;
687    }
688   
689  4361 if(value instanceof BigDecimal){
690  0 return longValue((BigDecimal) value);
691    }
692   
693  4361 if(value instanceof Number){
694  2253 return ((Number) value).longValue();
695    }
696   
697  2108 if(value instanceof String){
698  2101 String strVal = (String) value;
699  2101 if(strVal.length() == 0 //
700    || "null".equals(strVal) //
701    || "NULL".equals(strVal)){
702  14 return null;
703    }
704  2087 if(strVal.indexOf(',') != 0){
705  2087 strVal = strVal.replaceAll(",", "");
706    }
707  2087 try{
708  2087 return Long.parseLong(strVal);
709    } catch(NumberFormatException ex){
710    //
711    }
712  2 JSONScanner dateParser = new JSONScanner(strVal);
713  2 Calendar calendar = null;
714  2 if(dateParser.scanISO8601DateIfMatch(false)){
715  0 calendar = dateParser.getCalendar();
716    }
717  2 dateParser.close();
718  2 if(calendar != null){
719  0 return calendar.getTimeInMillis();
720    }
721    }
722   
723  9 if(value instanceof Map){
724  4 Map map = (Map) value;
725  4 if(map.size() == 2
726    && map.containsKey("andIncrement")
727    && map.containsKey("andDecrement")){
728  3 Iterator iter = map.values().iterator();
729  3 iter.next();
730  3 Object value2 = iter.next();
731  3 return castToLong(value2);
732    }
733    }
734   
735  6 Test failure here throw new JSONException("can not cast to long, value : " + value);
736    }
737   
 
738  6 toggle public static byte byteValue(BigDecimal decimal) {
739  6 if (decimal == null) {
740  0 return 0;
741    }
742   
743  6 int scale = decimal.scale();
744  6 if (scale >= -100 && scale <= 100) {
745  5 return decimal.byteValue();
746    }
747   
748  1 return decimal.byteValueExact();
749    }
750   
 
751  8 toggle public static short shortValue(BigDecimal decimal) {
752  8 if (decimal == null) {
753  0 return 0;
754    }
755   
756  8 int scale = decimal.scale();
757  8 if (scale >= -100 && scale <= 100) {
758  5 return decimal.shortValue();
759    }
760   
761  3 return decimal.shortValueExact();
762    }
763   
 
764  3918 toggle public static int intValue(BigDecimal decimal) {
765  3918 if (decimal == null) {
766  0 return 0;
767    }
768   
769  3918 int scale = decimal.scale();
770  3918 if (scale >= -100 && scale <= 100) {
771  3916 return decimal.intValue();
772    }
773   
774  2 return decimal.intValueExact();
775    }
776   
 
777  9 toggle public static long longValue(BigDecimal decimal) {
778  9 if (decimal == null) {
779  0 return 0;
780    }
781   
782  9 int scale = decimal.scale();
783  9 if (scale >= -100 && scale <= 100) {
784  7 return decimal.longValue();
785    }
786   
787  2 return decimal.longValueExact();
788    }
789   
 
790  313 toggle public static Integer castToInt(Object value){
791  313 if(value == null){
792  6 return null;
793    }
794   
795  307 if(value instanceof Integer){
796  262 return (Integer) value;
797    }
798   
799  45 if(value instanceof BigDecimal){
800  0 return intValue((BigDecimal) value);
801    }
802   
803  45 if(value instanceof Number){
804  10 return ((Number) value).intValue();
805    }
806   
807  35 if(value instanceof String){
808  28 String strVal = (String) value;
809  28 if(strVal.length() == 0 //
810    || "null".equals(strVal) //
811    || "NULL".equals(strVal)){
812  14 return null;
813    }
814  14 if(strVal.indexOf(',') != 0){
815  14 strVal = strVal.replaceAll(",", "");
816    }
817  14 return Integer.parseInt(strVal);
818    }
819   
820  7 if(value instanceof Boolean){
821  1 return ((Boolean) value).booleanValue() ? 1 : 0;
822    }
823  6 if(value instanceof Map){
824  4 Map map = (Map) value;
825  4 if(map.size() == 2
826    && map.containsKey("andIncrement")
827    && map.containsKey("andDecrement")){
828  3 Iterator iter = map.values().iterator();
829  3 iter.next();
830  3 Object value2 = iter.next();
831  3 return castToInt(value2);
832    }
833    }
834  3 throw new JSONException("can not cast to int, value : " + value);
835    }
836   
 
837  5 toggle public static byte[] castToBytes(Object value){
838  5 if(value instanceof byte[]){
839  1 return (byte[]) value;
840    }
841  4 if(value instanceof String){
842  3 return IOUtils.decodeBase64((String) value);
843    }
844  1 throw new JSONException("can not cast to int, value : " + value);
845    }
846   
 
847  185 toggle public static Boolean castToBoolean(Object value){
848  185 if(value == null){
849  2 return null;
850    }
851  183 if(value instanceof Boolean){
852  145 return (Boolean) value;
853    }
854   
855  38 if(value instanceof BigDecimal){
856  0 return intValue((BigDecimal) value) == 1;
857    }
858   
859  38 if(value instanceof Number){
860  6 return ((Number) value).intValue() == 1;
861    }
862   
863  32 if(value instanceof String){
864  29 String strVal = (String) value;
865  29 if(strVal.length() == 0 //
866    || "null".equals(strVal) //
867    || "NULL".equals(strVal)){
868  6 return null;
869    }
870  23 if("true".equalsIgnoreCase(strVal) //
871    || "1".equals(strVal)){
872  10 return Boolean.TRUE;
873    }
874  13 if("false".equalsIgnoreCase(strVal) //
875    || "0".equals(strVal)){
876  6 return Boolean.FALSE;
877    }
878  7 if("Y".equalsIgnoreCase(strVal) //
879    || "T".equals(strVal)){
880  3 return Boolean.TRUE;
881    }
882  4 if("F".equalsIgnoreCase(strVal) //
883    || "N".equals(strVal)){
884  2 return Boolean.FALSE;
885    }
886    }
887  5 throw new JSONException("can not cast to boolean, value : " + value);
888    }
889   
 
890  96 toggle public static <T> T castToJavaBean(Object obj, Class<T> clazz){
891  96 Test failure here return cast(obj, clazz, ParserConfig.getGlobalInstance());
892    }
893   
 
894  10068529 toggle @SuppressWarnings({"unchecked", "rawtypes"})
895    public static <T> T cast(Object obj, Class<T> clazz, ParserConfig config){
896  10068529 if(obj == null){
897  255 if(clazz == int.class){
898  1 return (T) Integer.valueOf(0);
899  254 } else if(clazz == long.class){
900  1 return (T) Long.valueOf(0);
901  253 } else if(clazz == short.class){
902  1 return (T) Short.valueOf((short) 0);
903  252 } else if(clazz == byte.class){
904  1 return (T) Byte.valueOf((byte) 0);
905  251 } else if(clazz == float.class){
906  1 return (T) Float.valueOf(0);
907  250 } else if(clazz == double.class){
908  1 return (T) Double.valueOf(0);
909  249 } else if(clazz == boolean.class){
910  1 return (T) Boolean.FALSE;
911    }
912  248 return null;
913    }
914   
915  10068274 if(clazz == null){
916  1 throw new IllegalArgumentException("clazz is null");
917    }
918   
919  10068273 if(clazz == obj.getClass()){
920  53343 return (T) obj;
921    }
922   
923  10014930 if(obj instanceof Map){
924  3700 if(clazz == Map.class){
925  2 return (T) obj;
926    }
927   
928  3698 Map map = (Map) obj;
929  3698 if(clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)){
930  3 return (T) obj;
931    }
932  3695 return castToJavaBean((Map<String,Object>) obj, clazz, config);
933    }
934   
935  10011230 if(clazz.isArray()){
936  4123 if(obj instanceof Collection){
937  4117 Collection collection = (Collection) obj;
938  4117 int index = 0;
939  4117 Object array = Array.newInstance(clazz.getComponentType(), collection.size());
940  4117 for(Object item : collection){
941  8230 Object value = cast(item, clazz.getComponentType(), config);
942  8230 Array.set(array, index, value);
943  8230 index++;
944    }
945  4117 return (T) array;
946    }
947  6 if(clazz == byte[].class){
948  1 return (T) castToBytes(obj);
949    }
950    }
951   
952  10007112 if(clazz.isAssignableFrom(obj.getClass())){
953  29 return (T) obj;
954    }
955   
956  10007083 if(clazz == boolean.class || clazz == Boolean.class){
957  136 return (T) castToBoolean(obj);
958    }
959   
960  10006947 if(clazz == byte.class || clazz == Byte.class){
961  9 return (T) castToByte(obj);
962    }
963   
964  10006938 if(clazz == char.class || clazz == Character.class){
965  3 return (T) castToChar(obj);
966    }
967   
968  10006935 if(clazz == short.class || clazz == Short.class){
969  134 return (T) castToShort(obj);
970    }
971   
972  10006801 if(clazz == int.class || clazz == Integer.class){
973  190 return (T) castToInt(obj);
974    }
975   
976  10006611 if(clazz == long.class || clazz == Long.class){
977  2209 return (T) castToLong(obj);
978    }
979   
980  10004402 if(clazz == float.class || clazz == Float.class){
981  10000142 return (T) castToFloat(obj);
982    }
983   
984  4260 if(clazz == double.class || clazz == Double.class){
985  136 return (T) castToDouble(obj);
986    }
987   
988  4124 if(clazz == String.class){
989  4 return (T) castToString(obj);
990    }
991   
992  4120 if(clazz == BigDecimal.class){
993  2 return (T) castToBigDecimal(obj);
994    }
995   
996  4118 if(clazz == BigInteger.class){
997  1 return (T) castToBigInteger(obj);
998    }
999   
1000  4117 if(clazz == Date.class){
1001  2042 Test failure here return (T) castToDate(obj);
1002    }
1003   
1004  2075 if(clazz == java.sql.Date.class){
1005  7 return (T) castToSqlDate(obj);
1006    }
1007   
1008  2068 if(clazz == java.sql.Time.class){
1009  2 return (T) castToSqlTime(obj);
1010    }
1011   
1012  2066 if(clazz == java.sql.Timestamp.class){
1013  16 return (T) castToTimestamp(obj);
1014    }
1015   
1016  2050 if(clazz.isEnum()){
1017  6 return castToEnum(obj, clazz, config);
1018    }
1019   
1020  2044 if(Calendar.class.isAssignableFrom(clazz)){
1021  11 Date date = castToDate(obj);
1022  11 Calendar calendar;
1023  11 if(clazz == Calendar.class){
1024  5 calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale);
1025    } else{
1026  6 try{
1027  6 calendar = (Calendar) clazz.newInstance();
1028    } catch(Exception e){
1029  1 throw new JSONException("can not cast to : " + clazz.getName(), e);
1030    }
1031    }
1032  10 calendar.setTime(date);
1033  10 return (T) calendar;
1034    }
1035   
1036  2033 String className = clazz.getName();
1037  2033 if(className.equals("javax.xml.datatype.XMLGregorianCalendar")){
1038  4 Date date = castToDate(obj);
1039  4 Calendar calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale);
1040  4 calendar.setTime(date);
1041  4 return (T) CalendarCodec.instance.createXMLGregorianCalendar(calendar);
1042    }
1043   
1044  2029 if(obj instanceof String){
1045  2026 String strVal = (String) obj;
1046  2026 if(strVal.length() == 0 //
1047    || "null".equals(strVal) //
1048    || "NULL".equals(strVal)){
1049  5 return null;
1050    }
1051   
1052  2021 if(clazz == java.util.Currency.class){
1053  2 return (T) java.util.Currency.getInstance(strVal);
1054    }
1055   
1056  2019 if(clazz == java.util.Locale.class){
1057  1 return (T) toLocale(strVal);
1058    }
1059   
1060  2018 if (className.startsWith("java.time.")) {
1061  1 String json = JSON.toJSONString(strVal);
1062  1 return JSON.parseObject(json, clazz);
1063    }
1064    }
1065   
1066  2020 final ObjectDeserializer objectDeserializer = config.get(clazz);
1067  2017 if (objectDeserializer != null) {
1068  2016 String str = JSON.toJSONString(obj);
1069  2016 return JSON.parseObject(str, clazz);
1070    }
1071  1 throw new JSONException("can not cast to : " + clazz.getName());
1072    }
1073   
 
1074  6 toggle public static Locale toLocale(String strVal){
1075  6 String[] items = strVal.split("_");
1076  6 if(items.length == 1){
1077  1 return new Locale(items[0]);
1078    }
1079  5 if(items.length == 2){
1080  4 return new Locale(items[0], items[1]);
1081    }
1082  1 return new Locale(items[0], items[1], items[2]);
1083    }
1084   
 
1085  10 toggle @SuppressWarnings({"unchecked", "rawtypes"})
1086    public static <T> T castToEnum(Object obj, Class<T> clazz, ParserConfig mapping){
1087  10 try{
1088  10 if(obj instanceof String){
1089  5 String name = (String) obj;
1090  5 if(name.length() == 0){
1091  2 return null;
1092    }
1093   
1094  3 if (mapping == null) {
1095  2 mapping = ParserConfig.getGlobalInstance();
1096    }
1097   
1098  3 ObjectDeserializer deserializer = mapping.getDeserializer(clazz);
1099  3 if (deserializer instanceof EnumDeserializer) {
1100  3 EnumDeserializer enumDeserializer = (EnumDeserializer) deserializer;
1101  3 return (T) enumDeserializer.getEnumByHashCode(TypeUtils.fnv1a_64(name));
1102    }
1103   
1104  0 return (T) Enum.valueOf((Class<? extends Enum>) clazz, name);
1105    }
1106   
1107  5 if(obj instanceof BigDecimal){
1108  0 int ordinal = intValue((BigDecimal) obj);
1109  0 Object[] values = clazz.getEnumConstants();
1110  0 if(ordinal < values.length){
1111  0 return (T) values[ordinal];
1112    }
1113    }
1114   
1115  5 if(obj instanceof Number){
1116  4 int ordinal = ((Number) obj).intValue();
1117  4 Object[] values = clazz.getEnumConstants();
1118  4 if(ordinal < values.length){
1119  2 return (T) values[ordinal];
1120    }
1121    }
1122    } catch(Exception ex){
1123  0 throw new JSONException("can not cast to : " + clazz.getName(), ex);
1124    }
1125  3 throw new JSONException("can not cast to : " + clazz.getName());
1126    }
1127   
 
1128  10245 toggle @SuppressWarnings("unchecked")
1129    public static <T> T cast(Object obj, Type type, ParserConfig mapping){
1130  10245 if(obj == null){
1131  1 return null;
1132    }
1133  10244 if(type instanceof Class){
1134  10213 return cast(obj, (Class<T>) type, mapping);
1135    }
1136  31 if(type instanceof ParameterizedType){
1137  26 return (T) cast(obj, (ParameterizedType) type, mapping);
1138    }
1139  5 if(obj instanceof String){
1140  5 String strVal = (String) obj;
1141  5 if(strVal.length() == 0 //
1142    || "null".equals(strVal) //
1143    || "NULL".equals(strVal)){
1144  3 return null;
1145    }
1146    }
1147  2 if(type instanceof TypeVariable){
1148  1 return (T) obj;
1149    }
1150  1 throw new JSONException("can not cast to : " + type);
1151    }
1152   
 
1153  35 toggle @SuppressWarnings({"rawtypes", "unchecked"})
1154    public static <T> T cast(Object obj, ParameterizedType type, ParserConfig mapping){
1155  35 Type rawTye = type.getRawType();
1156   
1157  35 if(rawTye == List.class || rawTye == ArrayList.class){
1158  11 Type itemType = type.getActualTypeArguments()[0];
1159  11 if(obj instanceof List){
1160  6 List listObj = (List) obj;
1161  6 List arrayList = new ArrayList(listObj.size());
1162   
1163  14 for (int i = 0; i < listObj.size(); i++) {
1164  8 Object item = listObj.get(i);
1165   
1166  8 Object itemValue;
1167  8 if (itemType instanceof Class) {
1168  8 if (item != null && item.getClass() == JSONObject.class) {
1169  4 itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
1170    } else {
1171  4 itemValue = cast(item, (Class<T>) itemType, mapping);
1172    }
1173    } else {
1174  0 itemValue = cast(item, itemType, mapping);
1175    }
1176   
1177  8 arrayList.add(itemValue);
1178    }
1179  6 return (T) arrayList;
1180    }
1181    }
1182   
1183  29 if(rawTye == Set.class || rawTye == HashSet.class //
1184    || rawTye == TreeSet.class //
1185    || rawTye == Collection.class //
1186    || rawTye == List.class //
1187    || rawTye == ArrayList.class){
1188  9 Type itemType = type.getActualTypeArguments()[0];
1189  9 if(obj instanceof Iterable){
1190  5 Collection collection;
1191  5 if(rawTye == Set.class || rawTye == HashSet.class){
1192  2 collection = new HashSet();
1193  3 } else if(rawTye == TreeSet.class){
1194  1 collection = new TreeSet();
1195    } else{
1196  2 collection = new ArrayList();
1197    }
1198  13 for(Iterator it = ((Iterable) obj).iterator(); it.hasNext(); ){
1199  8 Object item = it.next();
1200   
1201  8 Object itemValue;
1202  8 if (itemType instanceof Class) {
1203  8 if (item != null && item.getClass() == JSONObject.class) {
1204  1 itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
1205    } else {
1206  7 itemValue = cast(item, (Class<T>) itemType, mapping);
1207    }
1208    } else {
1209  0 itemValue = cast(item, itemType, mapping);
1210    }
1211   
1212  8 collection.add(itemValue);
1213    }
1214  5 return (T) collection;
1215    }
1216    }
1217   
1218  24 if(rawTye == Map.class || rawTye == HashMap.class){
1219  4 Type keyType = type.getActualTypeArguments()[0];
1220  4 Type valueType = type.getActualTypeArguments()[1];
1221  4 if(obj instanceof Map){
1222  3 Map map = new HashMap();
1223  3 for(Map.Entry entry : ((Map<?,?>) obj).entrySet()){
1224  3 Object key = cast(entry.getKey(), keyType, mapping);
1225  3 Object value = cast(entry.getValue(), valueType, mapping);
1226  3 map.put(key, value);
1227    }
1228  3 return (T) map;
1229    }
1230    }
1231  21 if(obj instanceof String){
1232  5 String strVal = (String) obj;
1233  5 if(strVal.length() == 0){
1234  3 return null;
1235    }
1236    }
1237  18 if(type.getActualTypeArguments().length == 1){
1238  5 Type argType = type.getActualTypeArguments()[0];
1239  5 if(argType instanceof WildcardType){
1240  2 return (T) cast(obj, rawTye, mapping);
1241    }
1242    }
1243   
1244  16 if (rawTye == Map.Entry.class && obj instanceof Map && ((Map) obj).size() == 1) {
1245  10 Map.Entry entry = (Map.Entry) ((Map) obj).entrySet().iterator().next();
1246  10 return (T) entry;
1247    }
1248   
1249  6 if (rawTye instanceof Class) {
1250  6 if (mapping == null) {
1251  3 mapping = ParserConfig.global;
1252    }
1253  6 ObjectDeserializer deserializer = mapping.getDeserializer(rawTye);
1254  6 if (deserializer != null) {
1255  6 String str = JSON.toJSONString(obj);
1256  6 DefaultJSONParser parser = new DefaultJSONParser(str, mapping);
1257  6 return (T) deserializer.deserialze(parser, type, null);
1258    }
1259    }
1260   
1261  0 throw new JSONException("can not cast to : " + type);
1262    }
1263   
 
1264  3742 toggle @SuppressWarnings({"unchecked"})
1265    public static <T> T castToJavaBean(Map<String,Object> map, Class<T> clazz, ParserConfig config){
1266  3742 try{
1267  3742 if(clazz == StackTraceElement.class){
1268  4 String declaringClass = (String) map.get("className");
1269  4 String methodName = (String) map.get("methodName");
1270  4 String fileName = (String) map.get("fileName");
1271  4 int lineNumber;
1272    {
1273  4 Number value = (Number) map.get("lineNumber");
1274  4 if(value == null) {
1275  1 lineNumber = 0;
1276  3 } else if (value instanceof BigDecimal) {
1277  0 lineNumber = ((BigDecimal) value).intValueExact();
1278    } else{
1279  3 lineNumber = value.intValue();
1280    }
1281    }
1282  4 return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber);
1283    }
1284   
1285    {
1286  3738 Object iClassObject = map.get(JSON.DEFAULT_TYPE_KEY);
1287  3738 if(iClassObject instanceof String){
1288  8 String className = (String) iClassObject;
1289  8 Class<?> loadClazz;
1290  8 if(config == null){
1291  3 config = ParserConfig.global;
1292    }
1293  8 loadClazz = config.checkAutoType(className, null);
1294  5 if(loadClazz == null){
1295  0 throw new ClassNotFoundException(className + " not found");
1296    }
1297  5 if(!loadClazz.equals(clazz)){
1298  3 return (T) castToJavaBean(map, loadClazz, config);
1299    }
1300    }
1301    }
1302   
1303  3732 if(clazz.isInterface()){
1304  8 JSONObject object;
1305  8 if(map instanceof JSONObject){
1306  5 object = (JSONObject) map;
1307    } else{
1308  3 object = new JSONObject(map);
1309    }
1310  8 if(config == null){
1311  1 config = ParserConfig.getGlobalInstance();
1312    }
1313  8 ObjectDeserializer deserializer = config.get(clazz);
1314  8 if(deserializer != null){
1315  4 String json = JSON.toJSONString(object);
1316  4 return JSON.parseObject(json, clazz);
1317    }
1318  4 return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
1319    new Class<?>[]{clazz}, object);
1320    }
1321   
1322  3724 if(clazz == Locale.class){
1323  1 Object arg0 = map.get("language");
1324  1 Object arg1 = map.get("country");
1325  1 if(arg0 instanceof String){
1326  1 String language = (String) arg0;
1327  1 if(arg1 instanceof String){
1328  1 String country = (String) arg1;
1329  1 return (T) new Locale(language, country);
1330  0 } else if(arg1 == null){
1331  0 return (T) new Locale(language);
1332    }
1333    }
1334    }
1335   
1336  3723 if (clazz == String.class && map instanceof JSONObject) {
1337  1 return (T) map.toString();
1338    }
1339   
1340  3722 if (clazz == JSON.class && map instanceof JSONObject) {
1341  1 return (T) map;
1342    }
1343   
1344  3721 if (clazz == LinkedHashMap.class && map instanceof JSONObject) {
1345  1 JSONObject jsonObject = (JSONObject) map;
1346  1 Map innerMap = jsonObject.getInnerMap();
1347  1 if (innerMap instanceof LinkedHashMap) {
1348  1 return (T) innerMap;
1349    } else {
1350  0 LinkedHashMap linkedHashMap = new LinkedHashMap();
1351  0 linkedHashMap.putAll(innerMap);
1352    }
1353    }
1354   
1355  3720 if (clazz.isInstance(map)) {
1356  1 return (T) map;
1357    }
1358   
1359  3719 if (clazz == JSONObject.class) {
1360  1 return (T) new JSONObject(map);
1361    }
1362   
1363  3718 if (config == null) {
1364  3 config = ParserConfig.getGlobalInstance();
1365    }
1366   
1367  3718 JavaBeanDeserializer javaBeanDeser = null;
1368  3718 ObjectDeserializer deserializer = config.getDeserializer(clazz);
1369  3718 if (deserializer instanceof JavaBeanDeserializer) {
1370  3716 javaBeanDeser = (JavaBeanDeserializer) deserializer;
1371    }
1372   
1373  3718 if(javaBeanDeser == null){
1374  2 throw new JSONException("can not get javaBeanDeserializer. " + clazz.getName());
1375    }
1376  3716 return (T) javaBeanDeser.createInstance(map, config);
1377    } catch(Exception e){
1378  17 Test failure here throw new JSONException(e.getMessage(), e);
1379    }
1380    }
1381   
 
1382  4 toggle private static void addBaseClassMappings(){
1383  4 mappings.put("byte", byte.class);
1384  4 mappings.put("short", short.class);
1385  4 mappings.put("int", int.class);
1386  4 mappings.put("long", long.class);
1387  4 mappings.put("float", float.class);
1388  4 mappings.put("double", double.class);
1389  4 mappings.put("boolean", boolean.class);
1390  4 mappings.put("char", char.class);
1391  4 mappings.put("[byte", byte[].class);
1392  4 mappings.put("[short", short[].class);
1393  4 mappings.put("[int", int[].class);
1394  4 mappings.put("[long", long[].class);
1395  4 mappings.put("[float", float[].class);
1396  4 mappings.put("[double", double[].class);
1397  4 mappings.put("[boolean", boolean[].class);
1398  4 mappings.put("[char", char[].class);
1399  4 mappings.put("[B", byte[].class);
1400  4 mappings.put("[S", short[].class);
1401  4 mappings.put("[I", int[].class);
1402  4 mappings.put("[J", long[].class);
1403  4 mappings.put("[F", float[].class);
1404  4 mappings.put("[D", double[].class);
1405  4 mappings.put("[C", char[].class);
1406  4 mappings.put("[Z", boolean[].class);
1407  4 Class<?>[] classes = new Class[]{
1408    Object.class,
1409    java.lang.Cloneable.class,
1410    loadClass("java.lang.AutoCloseable"),
1411    java.lang.Exception.class,
1412    java.lang.RuntimeException.class,
1413    java.lang.IllegalAccessError.class,
1414    java.lang.IllegalAccessException.class,
1415    java.lang.IllegalArgumentException.class,
1416    java.lang.IllegalMonitorStateException.class,
1417    java.lang.IllegalStateException.class,
1418    java.lang.IllegalThreadStateException.class,
1419    java.lang.IndexOutOfBoundsException.class,
1420    java.lang.InstantiationError.class,
1421    java.lang.InstantiationException.class,
1422    java.lang.InternalError.class,
1423    java.lang.InterruptedException.class,
1424    java.lang.LinkageError.class,
1425    java.lang.NegativeArraySizeException.class,
1426    java.lang.NoClassDefFoundError.class,
1427    java.lang.NoSuchFieldError.class,
1428    java.lang.NoSuchFieldException.class,
1429    java.lang.NoSuchMethodError.class,
1430    java.lang.NoSuchMethodException.class,
1431    java.lang.NullPointerException.class,
1432    java.lang.NumberFormatException.class,
1433    java.lang.OutOfMemoryError.class,
1434    java.lang.SecurityException.class,
1435    java.lang.StackOverflowError.class,
1436    java.lang.StringIndexOutOfBoundsException.class,
1437    java.lang.TypeNotPresentException.class,
1438    java.lang.VerifyError.class,
1439    java.lang.StackTraceElement.class,
1440    java.util.HashMap.class,
1441    java.util.Hashtable.class,
1442    java.util.TreeMap.class,
1443    java.util.IdentityHashMap.class,
1444    java.util.WeakHashMap.class,
1445    java.util.LinkedHashMap.class,
1446    java.util.HashSet.class,
1447    java.util.LinkedHashSet.class,
1448    java.util.TreeSet.class,
1449    java.util.ArrayList.class,
1450    java.util.concurrent.TimeUnit.class,
1451    java.util.concurrent.ConcurrentHashMap.class,
1452    loadClass("java.util.concurrent.ConcurrentSkipListMap"),
1453    loadClass("java.util.concurrent.ConcurrentSkipListSet"),
1454    java.util.concurrent.atomic.AtomicInteger.class,
1455    java.util.concurrent.atomic.AtomicLong.class,
1456    java.util.Collections.EMPTY_MAP.getClass(),
1457    java.lang.Boolean.class,
1458    java.lang.Character.class,
1459    java.lang.Byte.class,
1460    java.lang.Short.class,
1461    java.lang.Integer.class,
1462    java.lang.Long.class,
1463    java.lang.Float.class,
1464    java.lang.Double.class,
1465    java.lang.Number.class,
1466    java.lang.String.class,
1467    java.math.BigDecimal.class,
1468    java.math.BigInteger.class,
1469    java.util.BitSet.class,
1470    java.util.Calendar.class,
1471    java.util.Date.class,
1472    java.util.Locale.class,
1473    java.util.UUID.class,
1474    java.sql.Time.class,
1475    java.sql.Date.class,
1476    java.sql.Timestamp.class,
1477    java.text.SimpleDateFormat.class,
1478    com.alibaba.fastjson.JSONObject.class,
1479    com.alibaba.fastjson.JSONPObject.class,
1480    com.alibaba.fastjson.JSONArray.class,
1481    };
1482  4 for(Class clazz : classes){
1483  292 if(clazz == null){
1484  0 continue;
1485    }
1486  292 mappings.put(clazz.getName(), clazz);
1487    }
1488   
1489  4 String[] w = new String[]{
1490    "java.util.Collections$UnmodifiableMap"
1491    };
1492  4 for(String className : w){
1493  4 Class<?> clazz = loadClass(className);
1494  4 if(clazz == null){
1495  0 break;
1496    }
1497  4 mappings.put(clazz.getName(), clazz);
1498    }
1499   
1500  4 String[] awt = new String[]{
1501    "java.awt.Rectangle",
1502    "java.awt.Point",
1503    "java.awt.Font",
1504    "java.awt.Color"};
1505  4 for(String className : awt){
1506  16 Class<?> clazz = loadClass(className);
1507  16 if(clazz == null){
1508  0 break;
1509    }
1510  16 mappings.put(clazz.getName(), clazz);
1511    }
1512   
1513  4 String[] spring = new String[]{
1514    "org.springframework.util.LinkedMultiValueMap",
1515    "org.springframework.util.LinkedCaseInsensitiveMap",
1516    "org.springframework.remoting.support.RemoteInvocation",
1517    "org.springframework.remoting.support.RemoteInvocationResult",
1518    "org.springframework.security.web.savedrequest.DefaultSavedRequest",
1519    "org.springframework.security.web.savedrequest.SavedCookie",
1520    "org.springframework.security.web.csrf.DefaultCsrfToken",
1521    "org.springframework.security.web.authentication.WebAuthenticationDetails",
1522    "org.springframework.security.core.context.SecurityContextImpl",
1523    "org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
1524    "org.springframework.security.core.authority.SimpleGrantedAuthority",
1525    "org.springframework.security.core.userdetails.User",
1526    "org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken",
1527    "org.springframework.security.oauth2.common.DefaultOAuth2AccessToken",
1528    "org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken",
1529    "org.springframework.cache.support.NullValue",
1530    "org.springframework.jdbc.UncategorizedSQLException",
1531    "org.springframework.dao.CannotAcquireLockException",
1532    "org.springframework.dao.DuplicateKeyException",
1533    "org.springframework.dao.QueryTimeoutException",
1534    "org.springframework.dao.TransientDataAccessException",
1535    "org.springframework.dao.TypeMismatchDataAccessException",
1536    "org.springframework.dao.UncategorizedDataAccessException",
1537    "org.springframework.dao.DataAccessResourceFailureException",
1538    };
1539  4 for(String className : spring){
1540  96 Class<?> clazz = loadClass(className);
1541  96 if(clazz == null){
1542  4 continue;
1543    }
1544  92 mappings.put(clazz.getName(), clazz);
1545    }
1546   
1547  4 String[] sofa = new String[] {
1548    "com.alipay.sofa.rpc.core.exception.SofaTimeOutException",
1549    };
1550   
1551  4 for(String className : sofa){
1552  4 Class<?> clazz = loadClass(className);
1553  4 if(clazz == null){
1554  4 continue;
1555    }
1556  0 mappings.put(clazz.getName(), clazz);
1557    }
1558    }
1559   
 
1560  3 toggle public static void clearClassMapping(){
1561  3 mappings.clear();
1562  3 addBaseClassMappings();
1563    }
1564   
 
1565  29 toggle public static void addMapping(String className, Class<?> clazz) {
1566  29 mappings.put(className, clazz);
1567    }
1568   
 
1569  140 toggle public static Class<?> loadClass(String className){
1570  140 return loadClass(className, null);
1571    }
1572   
 
1573  1616 toggle public static boolean isPath(Class<?> clazz){
1574  1615 if(pathClass == null && !pathClass_error){
1575  1 try{
1576  1 pathClass = Class.forName("java.nio.file.Path");
1577    } catch(Throwable ex){
1578  0 pathClass_error = true;
1579    }
1580    }
1581  1616 if(pathClass != null){
1582  1617 return pathClass.isAssignableFrom(clazz);
1583    }
1584  0 return false;
1585    }
1586   
 
1587  12973 toggle public static Class<?> getClassFromMapping(String className){
1588  12973 return mappings.get(className);
1589    }
1590   
 
1591  152 toggle public static Class<?> loadClass(String className, ClassLoader classLoader) {
1592  152 return loadClass(className, classLoader, false);
1593    }
1594   
 
1595  282 toggle public static Class<?> loadClass(String className, ClassLoader classLoader, boolean cache) {
1596  282 if(className == null || className.length() == 0 || className.length() > 128){
1597  2 return null;
1598    }
1599   
1600  280 Class<?> clazz = mappings.get(className);
1601  280 if(clazz != null){
1602  32 return clazz;
1603    }
1604   
1605  248 if(className.charAt(0) == '['){
1606  6 Class<?> componentType = loadClass(className.substring(1), classLoader);
1607  6 return Array.newInstance(componentType, 0).getClass();
1608    }
1609   
1610  242 if(className.startsWith("L") && className.endsWith(";")){
1611  3 String newClassName = className.substring(1, className.length() - 1);
1612  3 return loadClass(newClassName, classLoader);
1613    }
1614   
1615  239 try{
1616  239 if(classLoader != null){
1617  2 clazz = classLoader.loadClass(className);
1618  1 if (cache) {
1619  0 mappings.put(className, clazz);
1620    }
1621  1 return clazz;
1622    }
1623    } catch(Throwable e){
1624  1 e.printStackTrace();
1625    // skip
1626    }
1627  238 try{
1628  238 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
1629  238 if(contextClassLoader != null && contextClassLoader != classLoader){
1630  237 clazz = contextClassLoader.loadClass(className);
1631  216 if (cache) {
1632  71 mappings.put(className, clazz);
1633    }
1634  216 return clazz;
1635    }
1636    } catch(Throwable e){
1637    // skip
1638    }
1639  22 try{
1640  22 clazz = Class.forName(className);
1641  1 if (cache) {
1642  0 mappings.put(className, clazz);
1643    }
1644  1 return clazz;
1645    } catch(Throwable e){
1646    // skip
1647    }
1648  21 return clazz;
1649    }
1650   
 
1651  21 toggle public static SerializeBeanInfo buildBeanInfo(Class<?> beanType //
1652    , Map<String,String> aliasMap //
1653    , PropertyNamingStrategy propertyNamingStrategy){
1654  21 return buildBeanInfo(beanType, aliasMap, propertyNamingStrategy, false);
1655    }
1656   
 
1657  1590 toggle public static SerializeBeanInfo buildBeanInfo(Class<?> beanType //
1658    , Map<String,String> aliasMap //
1659    , PropertyNamingStrategy propertyNamingStrategy //
1660    , boolean fieldBased //
1661    ){
1662  1591 JSONType jsonType = TypeUtils.getAnnotation(beanType,JSONType.class);
1663  1592 String[] orders = null;
1664  1592 final int features;
1665  1592 String typeName = null, typeKey = null;
1666  1592 if(jsonType != null){
1667  55 orders = jsonType.orders();
1668   
1669  55 typeName = jsonType.typeName();
1670  55 if(typeName.length() == 0){
1671  50 typeName = null;
1672    }
1673   
1674  55 PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
1675  55 if (jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
1676  3 propertyNamingStrategy = jsonTypeNaming;
1677    }
1678   
1679  55 features = SerializerFeature.of(jsonType.serialzeFeatures());
1680  55 for(Class<?> supperClass = beanType.getSuperclass()
1681  60 ; supperClass != null && supperClass != Object.class
1682    ; supperClass = supperClass.getSuperclass()){
1683  12 JSONType superJsonType = TypeUtils.getAnnotation(supperClass,JSONType.class);
1684  12 if(superJsonType == null){
1685  7 break;
1686    }
1687  5 typeKey = superJsonType.typeKey();
1688  5 if(typeKey.length() != 0){
1689  0 break;
1690    }
1691    }
1692   
1693  55 for(Class<?> interfaceClass : beanType.getInterfaces()){
1694  5 JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass,JSONType.class);
1695  5 if(superJsonType != null){
1696  2 typeKey = superJsonType.typeKey();
1697  2 if(typeKey.length() != 0){
1698  2 break;
1699    }
1700    }
1701    }
1702   
1703  55 if(typeKey != null && typeKey.length() == 0){
1704  4 typeKey = null;
1705    }
1706    } else{
1707  1537 features = 0;
1708    }
1709    // fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
1710  1592 Map<String,Field> fieldCacheMap = new HashMap<String,Field>();
1711  1592 ParserConfig.parserAllFieldToCache(beanType, fieldCacheMap);
1712  1592 List<FieldInfo> fieldInfoList = fieldBased
1713    ? computeGettersWithFieldBase(beanType, aliasMap, false, propertyNamingStrategy) //
1714    : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, false, propertyNamingStrategy);
1715  1592 FieldInfo[] fields = new FieldInfo[fieldInfoList.size()];
1716  1591 fieldInfoList.toArray(fields);
1717  1592 FieldInfo[] sortedFields;
1718  1592 List<FieldInfo> sortedFieldList;
1719  1591 if(orders != null && orders.length != 0){
1720  9 sortedFieldList = fieldBased
1721    ? computeGettersWithFieldBase(beanType, aliasMap, true, propertyNamingStrategy) //
1722    : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, true, propertyNamingStrategy);
1723    } else{
1724  1582 sortedFieldList = new ArrayList<FieldInfo>(fieldInfoList);
1725  1583 Collections.sort(sortedFieldList);
1726    }
1727  1592 sortedFields = new FieldInfo[sortedFieldList.size()];
1728  1592 sortedFieldList.toArray(sortedFields);
1729  1592 if(Arrays.equals(sortedFields, fields)){
1730  1105 sortedFields = fields;
1731    }
1732  1591 return new SerializeBeanInfo(beanType, jsonType, typeName, typeKey, features, fields, sortedFields);
1733    }
1734   
 
1735  2 toggle public static List<FieldInfo> computeGettersWithFieldBase(
1736    Class<?> clazz, //
1737    Map<String,String> aliasMap, //
1738    boolean sorted, //
1739    PropertyNamingStrategy propertyNamingStrategy){
1740  2 Map<String,FieldInfo> fieldInfoMap = new LinkedHashMap<String,FieldInfo>();
1741  7 for(Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()){
1742  5 Field[] fields = currentClass.getDeclaredFields();
1743  5 computeFields(currentClass, aliasMap, propertyNamingStrategy, fieldInfoMap, fields);
1744    }
1745  2 return getFieldInfos(clazz, sorted, fieldInfoMap);
1746    }
1747   
 
1748  1 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String,String> aliasMap){
1749  1 return computeGetters(clazz, aliasMap, true);
1750    }
1751   
 
1752  1 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String,String> aliasMap, boolean sorted){
1753  1 JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
1754  1 Map<String,Field> fieldCacheMap = new HashMap<String,Field>();
1755  1 ParserConfig.parserAllFieldToCache(clazz, fieldCacheMap);
1756  1 return computeGetters(clazz, jsonType, aliasMap, fieldCacheMap, sorted, PropertyNamingStrategy.CamelCase);
1757    }
1758   
 
1759  1600 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, //
1760    JSONType jsonType, //
1761    Map<String,String> aliasMap, //
1762    Map<String,Field> fieldCacheMap, //
1763    boolean sorted, //
1764    PropertyNamingStrategy propertyNamingStrategy //
1765    ){
1766  1600 Map<String,FieldInfo> fieldInfoMap = new LinkedHashMap<String,FieldInfo>();
1767  1600 boolean kotlin = TypeUtils.isKotlin(clazz);
1768    // for kotlin
1769  1600 Constructor[] constructors = null;
1770  1600 Annotation[][] paramAnnotationArrays = null;
1771  1600 String[] paramNames = null;
1772  1599 short[] paramNameMapping = null;
1773  1600 Method[] methods = clazz.getMethods();
1774  1600 for(Method method : methods){
1775  21333 String methodName = method.getName();
1776  21335 int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
1777  21331 String label = null;
1778  21326 if(Modifier.isStatic(method.getModifiers())){
1779  148 continue;
1780    }
1781  21188 if(method.getReturnType().equals(Void.TYPE)){
1782  11071 continue;
1783    }
1784  10123 if(method.getParameterTypes().length != 0){
1785  1745 continue;
1786    }
1787  8378 if(method.getReturnType() == ClassLoader.class){
1788  1 continue;
1789    }
1790   
1791  8375 if(methodName.equals("getMetaClass")
1792    && method.getReturnType().getName().equals("groovy.lang.MetaClass")){
1793  2 continue;
1794    }
1795  8372 if(methodName.equals("getSuppressed")
1796    && method.getDeclaringClass() == Throwable.class){
1797  8 continue;
1798    }
1799   
1800  8364 if(kotlin && isKotlinIgnore(clazz, methodName)){
1801  0 continue;
1802    }
1803    /**
1804    * 如果在属性或者方法上存在JSONField注解,并且定制了name属性,不以类上的propertyNamingStrategy设置为准,以此字段的JSONField的name定制为准。
1805    */
1806  8361 Boolean fieldAnnotationAndNameExists = false;
1807  8363 JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class);
1808  8362 if(annotation == null){
1809  8290 annotation = getSuperMethodAnnotation(clazz, method);
1810    }
1811  8367 if(annotation == null && kotlin){
1812  168 if(constructors == null){
1813  20 constructors = clazz.getDeclaredConstructors();
1814  20 Constructor creatorConstructor = TypeUtils.getKoltinConstructor(constructors);
1815  20 if(creatorConstructor != null){
1816  20 paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor);
1817  20 paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
1818  20 if(paramNames != null){
1819  20 String[] paramNames_sorted = new String[paramNames.length];
1820  20 System.arraycopy(paramNames, 0, paramNames_sorted, 0, paramNames.length);
1821   
1822  20 Arrays.sort(paramNames_sorted);
1823  20 paramNameMapping = new short[paramNames.length];
1824  71 for(short p = 0; p < paramNames.length; p++){
1825  51 int index = Arrays.binarySearch(paramNames_sorted, paramNames[p]);
1826  51 paramNameMapping[index] = p;
1827    }
1828  20 paramNames = paramNames_sorted;
1829    }
1830    }
1831    }
1832  168 if(paramNames != null && paramNameMapping != null && methodName.startsWith("get")){
1833  85 String propertyName = decapitalize(methodName.substring(3));
1834  85 int p = Arrays.binarySearch(paramNames, propertyName);
1835  85 if (p < 0) {
1836  98 for (int i = 0; i < paramNames.length; i++) {
1837  64 if (propertyName.equalsIgnoreCase(paramNames[i])) {
1838  2 p = i;
1839  2 break;
1840    }
1841    }
1842    }
1843  85 if(p >= 0){
1844  51 short index = paramNameMapping[p];
1845  51 Annotation[] paramAnnotations = paramAnnotationArrays[index];
1846  51 if(paramAnnotations != null){
1847  51 for(Annotation paramAnnotation : paramAnnotations){
1848  22 if(paramAnnotation instanceof JSONField){
1849  22 annotation = (JSONField) paramAnnotation;
1850  22 break;
1851    }
1852    }
1853    }
1854  51 if(annotation == null){
1855  29 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1856  29 if(field != null){
1857  29 annotation = TypeUtils.getAnnotation(field, JSONField.class);
1858    }
1859    }
1860    }
1861    }
1862    }
1863  8363 if(annotation != null){
1864  102 if(!annotation.serialize()){
1865  8 continue;
1866    }
1867  94 ordinal = annotation.ordinal();
1868  94 serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
1869  94 parserFeatures = Feature.of(annotation.parseFeatures());
1870  94 if(annotation.name().length() != 0){
1871  44 String propertyName = annotation.name();
1872  44 if(aliasMap != null){
1873  1 propertyName = aliasMap.get(propertyName);
1874  1 if(propertyName == null){
1875  1 continue;
1876    }
1877    }
1878  43 FieldInfo fieldInfo = new FieldInfo(propertyName, method, null, clazz, null, ordinal,
1879    serialzeFeatures, parserFeatures, annotation, null, label);
1880  43 fieldInfoMap.put(propertyName, fieldInfo);
1881  43 continue;
1882    }
1883  50 if(annotation.label().length() != 0){
1884  12 label = annotation.label();
1885    }
1886    }
1887  8310 if(methodName.startsWith("get")){
1888  4918 if(methodName.length() < 4){
1889  7 continue;
1890    }
1891  4913 if(methodName.equals("getClass")){
1892  1588 continue;
1893    }
1894  3322 if(methodName.equals("getDeclaringClass") && clazz.isEnum()){
1895  8 continue;
1896    }
1897  3313 char c3 = methodName.charAt(3);
1898  3311 String propertyName;
1899  3311 if(Character.isUpperCase(c3) //
1900    || c3 > 512 // for unicode method name
1901    ){
1902  3284 if(compatibleWithJavaBean){
1903  1 propertyName = decapitalize(methodName.substring(3));
1904    } else{
1905  3285 propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
1906    }
1907  3292 propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 3);
1908  27 } else if(c3 == '_'){
1909  2 propertyName = methodName.substring(4);
1910  25 } else if(c3 == 'f'){
1911  1 propertyName = methodName.substring(3);
1912  24 } else if(methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))){
1913  17 propertyName = decapitalize(methodName.substring(3));
1914    } else{
1915  7 continue;
1916    }
1917  3312 boolean ignore = isJSONTypeIgnore(clazz, propertyName);
1918  3312 if(ignore){
1919  11 continue;
1920    }
1921    //假如bean的field很多的情况一下,轮询时将大大降低效率
1922  3301 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1923  3302 if(field == null && propertyName.length() > 1){
1924  124 char ch = propertyName.charAt(1);
1925  124 if(ch >= 'A' && ch <= 'Z'){
1926  3 String javaBeanCompatiblePropertyName = decapitalize(methodName.substring(3));
1927  3 field = ParserConfig.getFieldFromCache(javaBeanCompatiblePropertyName, fieldCacheMap);
1928    }
1929    }
1930  3302 JSONField fieldAnnotation = null;
1931  3302 if(field != null){
1932  3177 fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
1933  3178 if(fieldAnnotation != null){
1934  106 if(!fieldAnnotation.serialize()){
1935  9 continue;
1936    }
1937  97 ordinal = fieldAnnotation.ordinal();
1938  97 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
1939  97 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
1940  97 if(fieldAnnotation.name().length() != 0){
1941  34 fieldAnnotationAndNameExists = true;
1942  34 propertyName = fieldAnnotation.name();
1943  34 if(aliasMap != null){
1944  1 propertyName = aliasMap.get(propertyName);
1945  1 if(propertyName == null){
1946  1 continue;
1947    }
1948    }
1949    }
1950  96 if(fieldAnnotation.label().length() != 0){
1951  0 label = fieldAnnotation.label();
1952    }
1953    }
1954    }
1955  3294 if(aliasMap != null){
1956  5 propertyName = aliasMap.get(propertyName);
1957  5 if(propertyName == null){
1958  3 continue;
1959    }
1960    }
1961  3290 if(propertyNamingStrategy != null && !fieldAnnotationAndNameExists){
1962  265 propertyName = propertyNamingStrategy.translate(propertyName);
1963    }
1964  3290 FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
1965    annotation, fieldAnnotation, label);
1966  3286 fieldInfoMap.put(propertyName, fieldInfo);
1967    }
1968  6679 if(methodName.startsWith("is")){
1969  91 if(methodName.length() < 3){
1970  7 continue;
1971    }
1972  84 if(method.getReturnType() != Boolean.TYPE
1973    && method.getReturnType() != Boolean.class){
1974  1 continue;
1975    }
1976  83 char c2 = methodName.charAt(2);
1977  83 String propertyName;
1978  83 if(Character.isUpperCase(c2)){
1979  74 if(compatibleWithJavaBean){
1980  1 propertyName = decapitalize(methodName.substring(2));
1981    } else{
1982  73 propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3);
1983    }
1984  74 propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 2);
1985  9 } else if(c2 == '_'){
1986  1 propertyName = methodName.substring(3);
1987  8 } else if(c2 == 'f'){
1988  1 propertyName = methodName.substring(2);
1989    } else{
1990  7 continue;
1991    }
1992  76 boolean ignore = isJSONTypeIgnore(clazz, propertyName);
1993  76 if(ignore){
1994  1 continue;
1995    }
1996  75 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1997  75 if(field == null){
1998  21 field = ParserConfig.getFieldFromCache(methodName, fieldCacheMap);
1999    }
2000  75 JSONField fieldAnnotation = null;
2001  75 if(field != null){
2002  59 fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
2003  59 if(fieldAnnotation != null){
2004  7 if(!fieldAnnotation.serialize()){
2005  3 continue;
2006    }
2007  4 ordinal = fieldAnnotation.ordinal();
2008  4 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
2009  4 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
2010  4 if(fieldAnnotation.name().length() != 0){
2011  3 propertyName = fieldAnnotation.name();
2012  3 if(aliasMap != null){
2013  1 propertyName = aliasMap.get(propertyName);
2014  1 if(propertyName == null){
2015  1 continue;
2016    }
2017    }
2018    }
2019  3 if(fieldAnnotation.label().length() != 0){
2020  0 label = fieldAnnotation.label();
2021    }
2022    }
2023    }
2024  71 if(aliasMap != null){
2025  1 propertyName = aliasMap.get(propertyName);
2026  1 if(propertyName == null){
2027  1 continue;
2028    }
2029    }
2030  70 if(propertyNamingStrategy != null){
2031  1 propertyName = propertyNamingStrategy.translate(propertyName);
2032    }
2033    //优先选择get
2034  70 if(fieldInfoMap.containsKey(propertyName)){
2035  0 continue;
2036    }
2037  70 FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
2038    annotation, fieldAnnotation, label);
2039  70 fieldInfoMap.put(propertyName, fieldInfo);
2040    }
2041    }
2042  1600 Field[] fields = clazz.getFields();
2043  1600 computeFields(clazz, aliasMap, propertyNamingStrategy, fieldInfoMap, fields);
2044  1600 return getFieldInfos(clazz, sorted, fieldInfoMap);
2045    }
2046   
 
2047  1602 toggle private static List<FieldInfo> getFieldInfos(Class<?> clazz, boolean sorted, Map<String,FieldInfo> fieldInfoMap){
2048  1602 List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
2049  1602 String[] orders = null;
2050  1602 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2051  1602 if(annotation != null){
2052  64 orders = annotation.orders();
2053    }
2054  1602 if(orders != null && orders.length > 0){
2055  18 LinkedHashMap<String,FieldInfo> map = new LinkedHashMap<String,FieldInfo>(fieldInfoList.size());
2056  18 for(FieldInfo field : fieldInfoMap.values()){
2057  56 map.put(field.name, field);
2058    }
2059  18 int i = 0;
2060  18 for(String item : orders){
2061  52 FieldInfo field = map.get(item);
2062  52 if(field != null){
2063  50 fieldInfoList.add(field);
2064  50 map.remove(item);
2065    }
2066    }
2067  18 for(FieldInfo field : map.values()){
2068  6 fieldInfoList.add(field);
2069    }
2070    } else{
2071  1584 for(FieldInfo fieldInfo : fieldInfoMap.values()){
2072  10543 fieldInfoList.add(fieldInfo);
2073    }
2074  1584 if(sorted){
2075  1 Collections.sort(fieldInfoList);
2076    }
2077    }
2078  1602 return fieldInfoList;
2079    }
2080   
 
2081  1605 toggle private static void computeFields(
2082    Class<?> clazz, //
2083    Map<String,String> aliasMap, //
2084    PropertyNamingStrategy propertyNamingStrategy, //
2085    Map<String,FieldInfo> fieldInfoMap, //
2086    Field[] fields){
2087  1605 for(Field field : fields){
2088  7350 if(Modifier.isStatic(field.getModifiers())){
2089  102 continue;
2090    }
2091  7248 JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
2092  7248 int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
2093  7248 String propertyName = field.getName();
2094  7248 String label = null;
2095  7248 if(fieldAnnotation != null){
2096  86 if(!fieldAnnotation.serialize()){
2097  3 continue;
2098    }
2099  83 ordinal = fieldAnnotation.ordinal();
2100  83 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
2101  83 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
2102  83 if(fieldAnnotation.name().length() != 0){
2103  27 propertyName = fieldAnnotation.name();
2104    }
2105  83 if(fieldAnnotation.label().length() != 0){
2106  0 label = fieldAnnotation.label();
2107    }
2108    }
2109  7245 if(aliasMap != null){
2110  2 propertyName = aliasMap.get(propertyName);
2111  2 if(propertyName == null){
2112  1 continue;
2113    }
2114    }
2115  7244 if(propertyNamingStrategy != null){
2116  4 propertyName = propertyNamingStrategy.translate(propertyName);
2117    }
2118  7244 if(!fieldInfoMap.containsKey(propertyName)){
2119  7207 FieldInfo fieldInfo = new FieldInfo(propertyName, null, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
2120    null, fieldAnnotation, label);
2121  7207 fieldInfoMap.put(propertyName, fieldInfo);
2122    }
2123    }
2124    }
2125   
 
2126  3365 toggle private static String getPropertyNameByCompatibleFieldName(Map<String,Field> fieldCacheMap, String methodName,
2127    String propertyName, int fromIdx){
2128  3366 if(compatibleWithFieldName){
2129  0 if(!fieldCacheMap.containsKey(propertyName)){
2130  0 String tempPropertyName = methodName.substring(fromIdx);
2131  0 return fieldCacheMap.containsKey(tempPropertyName) ? tempPropertyName : propertyName;
2132    }
2133    }
2134  3365 return propertyName;
2135    }
2136   
 
2137  12720 toggle public static JSONField getSuperMethodAnnotation(final Class<?> clazz, final Method method){
2138  12721 Class<?>[] interfaces = clazz.getInterfaces();
2139  12724 if(interfaces.length > 0){
2140  1618 Class<?>[] types = method.getParameterTypes();
2141  1618 for(Class<?> interfaceClass : interfaces){
2142  1690 for(Method interfaceMethod : interfaceClass.getMethods()){
2143  1934 Class<?>[] interfaceTypes = interfaceMethod.getParameterTypes();
2144  1934 if(interfaceTypes.length != types.length){
2145  950 continue;
2146    }
2147  984 if(!interfaceMethod.getName().equals(method.getName())){
2148  883 continue;
2149    }
2150  101 boolean match = true;
2151  115 for(int i = 0; i < types.length; ++i){
2152  18 if(!interfaceTypes[i].equals(types[i])){
2153  4 match = false;
2154  4 break;
2155    }
2156    }
2157  101 if(!match){
2158  4 continue;
2159    }
2160  97 JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class);
2161  97 if(annotation != null){
2162  7 return annotation;
2163    }
2164    }
2165    }
2166    }
2167  12717 Class<?> superClass = clazz.getSuperclass();
2168  12718 if(superClass == null){
2169  69 return null;
2170    }
2171  12649 if(Modifier.isAbstract(superClass.getModifiers())){
2172  279 Class<?>[] types = method.getParameterTypes();
2173  279 for(Method interfaceMethod : superClass.getMethods()){
2174  6605 Class<?>[] interfaceTypes = interfaceMethod.getParameterTypes();
2175  6605 if(interfaceTypes.length != types.length){
2176  3080 continue;
2177    }
2178  3525 if(!interfaceMethod.getName().equals(method.getName())){
2179  3295 continue;
2180    }
2181  230 boolean match = true;
2182  243 for(int i = 0; i < types.length; ++i){
2183  13 if(!interfaceTypes[i].equals(types[i])){
2184  0 match = false;
2185  0 break;
2186    }
2187    }
2188  230 if(!match){
2189  0 continue;
2190    }
2191  230 JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class);
2192  230 if(annotation != null){
2193  1 return annotation;
2194    }
2195    }
2196    }
2197  12648 return null;
2198    }
2199   
 
2200  3854 toggle private static boolean isJSONTypeIgnore(Class<?> clazz, String propertyName){
2201  3854 JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
2202  3857 if(jsonType != null){
2203    // 1、新增 includes 支持,如果 JSONType 同时设置了includes 和 ignores 属性,则以includes为准。
2204    // 2、个人认为对于大小写敏感的Java和JS而言,使用 equals() 比 equalsIgnoreCase() 更好,改动的唯一风险就是向后兼容性的问题
2205    // 不过,相信开发者应该都是严格按照大小写敏感的方式进行属性设置的
2206  151 String[] fields = jsonType.includes();
2207  151 if(fields.length > 0){
2208  5 for(int i = 0; i < fields.length; i++){
2209  3 if(propertyName.equals(fields[i])){
2210  1 return false;
2211    }
2212    }
2213  2 return true;
2214    } else{
2215  148 fields = jsonType.ignores();
2216  182 for(int i = 0; i < fields.length; i++){
2217  44 if(propertyName.equals(fields[i])){
2218  10 return true;
2219    }
2220    }
2221    }
2222    }
2223  3843 if(clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null){
2224  467 return isJSONTypeIgnore(clazz.getSuperclass(), propertyName);
2225    }
2226  3376 return false;
2227    }
2228   
 
2229  1374 toggle public static boolean isGenericParamType(Type type){
2230  1372 if(type instanceof ParameterizedType){
2231  329 return true;
2232    }
2233  1042 if(type instanceof Class) {
2234  1039 Type superType = ((Class<?>) type).getGenericSuperclass();
2235  1041 return superType != Object.class && isGenericParamType(superType);
2236    }
2237  3 return false;
2238    }
2239   
 
2240  31 toggle public static Type getGenericParamType(Type type){
2241  31 if(type instanceof ParameterizedType){
2242  27 return type;
2243    }
2244  4 if(type instanceof Class){
2245  4 return getGenericParamType(((Class<?>) type).getGenericSuperclass());
2246    }
2247  0 return type;
2248    }
2249   
 
2250  5 toggle public static Type unwrapOptional(Type type){
2251  5 if(!optionalClassInited){
2252  1 try{
2253  1 optionalClass = Class.forName("java.util.Optional");
2254    } catch(Exception e){
2255    // skip
2256    } finally{
2257  1 optionalClassInited = true;
2258    }
2259    }
2260  5 if(type instanceof ParameterizedType){
2261  5 ParameterizedType parameterizedType = (ParameterizedType) type;
2262  5 if(parameterizedType.getRawType() == optionalClass){
2263  5 return parameterizedType.getActualTypeArguments()[0];
2264    }
2265    }
2266  0 return type;
2267    }
2268   
 
2269  253 toggle public static Class<?> getClass(Type type){
2270  253 if(type.getClass() == Class.class){
2271  164 return (Class<?>) type;
2272    }
2273   
2274  89 if(type instanceof ParameterizedType){
2275  68 return getClass(((ParameterizedType) type).getRawType());
2276    }
2277   
2278  21 if(type instanceof TypeVariable){
2279  15 Type boundType = ((TypeVariable<?>) type).getBounds()[0];
2280  15 if (boundType instanceof Class) {
2281  15 return (Class) boundType;
2282    }
2283  0 return getClass(boundType);
2284    }
2285   
2286  6 if(type instanceof WildcardType){
2287  6 Type[] upperBounds = ((WildcardType) type).getUpperBounds();
2288  6 if (upperBounds.length == 1) {
2289  6 return getClass(upperBounds[0]);
2290    }
2291    }
2292   
2293  0 return Object.class;
2294    }
2295   
 
2296  5306 toggle public static Field getField(Class<?> clazz, String fieldName, Field[] declaredFields){
2297  5306 for(Field field : declaredFields){
2298  169682 String itemName = field.getName();
2299  169682 if(fieldName.equals(itemName)){
2300  4972 return field;
2301    }
2302   
2303  164710 char c0, c1;
2304  ? if (fieldName.length() > 2
2305    && (c0 = fieldName.charAt(0)) >= 'a' && c0 <= 'z'
2306    && (c1 = fieldName.charAt(1)) >= 'A' && c1 <= 'Z'
2307    && fieldName.equalsIgnoreCase(itemName)) {
2308  8 return field;
2309    }
2310    }
2311  326 Class<?> superClass = clazz.getSuperclass();
2312  326 if(superClass != null && superClass != Object.class){
2313  167 return getField(superClass, fieldName, superClass.getDeclaredFields());
2314    }
2315  159 return null;
2316    }
2317   
2318    /**
2319    * @deprecated
2320    */
 
2321  2 toggle public static int getSerializeFeatures(Class<?> clazz){
2322  2 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2323  2 if(annotation == null){
2324  1 return 0;
2325    }
2326  1 return SerializerFeature.of(annotation.serialzeFeatures());
2327    }
2328   
 
2329  2695 toggle public static int getParserFeatures(Class<?> clazz){
2330  2695 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2331  2695 if(annotation == null){
2332  2576 return 0;
2333    }
2334  119 return Feature.of(annotation.parseFeatures());
2335    }
2336   
 
2337  147 toggle public static String decapitalize(String name){
2338  147 if(name == null || name.length() == 0){
2339  0 return name;
2340    }
2341  147 if(name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){
2342  9 return name;
2343    }
2344  138 char[] chars = name.toCharArray();
2345  138 chars[0] = Character.toLowerCase(chars[0]);
2346  138 return new String(chars);
2347    }
2348   
 
2349  37545 toggle static void setAccessible(AccessibleObject obj){
2350  37544 if(!setAccessibleEnable){
2351  0 return;
2352    }
2353  37546 if(obj.isAccessible()){
2354  10663 return;
2355    }
2356  26883 try{
2357  26882 obj.setAccessible(true);
2358    } catch(AccessControlException error){
2359  0 setAccessibleEnable = false;
2360    }
2361    }
2362   
 
2363  450 toggle public static Type getCollectionItemType(Type fieldType) {
2364  450 if (fieldType instanceof ParameterizedType) {
2365  396 return getCollectionItemType((ParameterizedType) fieldType);
2366    }
2367  54 if (fieldType instanceof Class<?>) {
2368  40 return getCollectionItemType((Class<?>) fieldType);
2369    }
2370  14 return Object.class;
2371    }
2372   
 
2373  40 toggle private static Type getCollectionItemType(Class<?> clazz) {
2374  40 return clazz.getName().startsWith("java.")
2375    ? Object.class
2376    : getCollectionItemType(getCollectionSuperType(clazz));
2377    }
2378   
 
2379  859 toggle private static Type getCollectionItemType(ParameterizedType parameterizedType) {
2380  859 Type rawType = parameterizedType.getRawType();
2381  859 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
2382  859 if (rawType == Collection.class) {
2383  396 return getWildcardTypeUpperBounds(actualTypeArguments[0]);
2384    }
2385  463 Class<?> rawClass = (Class<?>) rawType;
2386  463 Map<TypeVariable, Type> actualTypeMap = createActualTypeMap(rawClass.getTypeParameters(), actualTypeArguments);
2387  463 Type superType = getCollectionSuperType(rawClass);
2388  463 if (superType instanceof ParameterizedType) {
2389  463 Class<?> superClass = getRawClass(superType);
2390  463 Type[] superClassTypeParameters = ((ParameterizedType) superType).getActualTypeArguments();
2391  463 return superClassTypeParameters.length > 0
2392    ? getCollectionItemType(makeParameterizedType(superClass, superClassTypeParameters, actualTypeMap))
2393    : getCollectionItemType(superClass);
2394    }
2395  0 return getCollectionItemType((Class<?>) superType);
2396    }
2397   
 
2398  479 toggle private static Type getCollectionSuperType(Class<?> clazz) {
2399  479 Type assignable = null;
2400  479 for (Type type : clazz.getGenericInterfaces()) {
2401  561 Class<?> rawClass = getRawClass(type);
2402  561 if (rawClass == Collection.class) {
2403  370 return type;
2404    }
2405  191 if (Collection.class.isAssignableFrom(rawClass)) {
2406  84 assignable = type;
2407    }
2408    }
2409  109 return assignable == null ? clazz.getGenericSuperclass() : assignable;
2410    }
2411   
 
2412  463 toggle private static Map<TypeVariable, Type> createActualTypeMap(TypeVariable[] typeParameters, Type[] actualTypeArguments) {
2413  463 int length = typeParameters.length;
2414  463 Map<TypeVariable, Type> actualTypeMap = new HashMap<TypeVariable, Type>(length);
2415  935 for (int i = 0; i < length; i++) {
2416  472 actualTypeMap.put(typeParameters[i], actualTypeArguments[i]);
2417    }
2418  463 return actualTypeMap;
2419    }
2420   
 
2421  465 toggle private static ParameterizedType makeParameterizedType(Class<?> rawClass, Type[] typeParameters, Map<TypeVariable, Type> actualTypeMap) {
2422  465 int length = typeParameters.length;
2423  465 Type[] actualTypeArguments = new Type[length];
2424  939 for (int i = 0; i < length; i++) {
2425  474 actualTypeArguments[i] = getActualType(typeParameters[i], actualTypeMap);
2426    }
2427  465 return new ParameterizedTypeImpl(actualTypeArguments, null, rawClass);
2428    }
2429   
 
2430  478 toggle private static Type getActualType(Type typeParameter, Map<TypeVariable, Type> actualTypeMap) {
2431  478 if (typeParameter instanceof TypeVariable) {
2432  469 return actualTypeMap.get(typeParameter);
2433  9 } else if (typeParameter instanceof ParameterizedType) {
2434  2 return makeParameterizedType(getRawClass(typeParameter), ((ParameterizedType) typeParameter).getActualTypeArguments(), actualTypeMap);
2435  7 } else if (typeParameter instanceof GenericArrayType) {
2436  4 return new GenericArrayTypeImpl(getActualType(((GenericArrayType) typeParameter).getGenericComponentType(), actualTypeMap));
2437    }
2438  3 return typeParameter;
2439    }
2440   
 
2441  396 toggle private static Type getWildcardTypeUpperBounds(Type type) {
2442  396 if (type instanceof WildcardType) {
2443  13 WildcardType wildcardType = (WildcardType) type;
2444  13 Type[] upperBounds = wildcardType.getUpperBounds();
2445  13 return upperBounds.length > 0 ? upperBounds[0] : Object.class;
2446    }
2447  383 return type;
2448    }
2449   
 
2450  738 toggle public static Class<?> getCollectionItemClass(Type fieldType){
2451  738 if(fieldType instanceof ParameterizedType){
2452  722 Class<?> itemClass;
2453  722 Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
2454  722 if(actualTypeArgument instanceof WildcardType){
2455  6 WildcardType wildcardType = (WildcardType) actualTypeArgument;
2456  6 Type[] upperBounds = wildcardType.getUpperBounds();
2457  6 if(upperBounds.length == 1){
2458  6 actualTypeArgument = upperBounds[0];
2459    }
2460    }
2461  722 if(actualTypeArgument instanceof Class){
2462  718 itemClass = (Class<?>) actualTypeArgument;
2463  718 if(!Modifier.isPublic(itemClass.getModifiers())){
2464  2 throw new JSONException("can not create ASMParser");
2465    }
2466    } else{
2467  4 throw new JSONException("can not create ASMParser");
2468    }
2469  716 return itemClass;
2470    }
2471  16 return Object.class;
2472    }
2473   
 
2474  9 toggle public static Type checkPrimitiveArray(GenericArrayType genericArrayType) {
2475  9 Type clz = genericArrayType;
2476  9 Type genericComponentType = genericArrayType.getGenericComponentType();
2477   
2478  9 String prefix = "[";
2479  9 while (genericComponentType instanceof GenericArrayType) {
2480  0 genericComponentType = ((GenericArrayType) genericComponentType)
2481    .getGenericComponentType();
2482  0 prefix += prefix;
2483    }
2484   
2485  9 if (genericComponentType instanceof Class<?>) {
2486  8 Class<?> ck = (Class<?>) genericComponentType;
2487  8 if (ck.isPrimitive()) {
2488  8 try {
2489  8 if (ck == boolean.class) {
2490  1 clz = Class.forName(prefix + "Z");
2491  7 } else if (ck == char.class) {
2492  1 clz = Class.forName(prefix + "C");
2493  6 } else if (ck == byte.class) {
2494  1 clz = Class.forName(prefix + "B");
2495  5 } else if (ck == short.class) {
2496  1 clz = Class.forName(prefix + "S");
2497  4 } else if (ck == int.class) {
2498  1 clz = Class.forName(prefix + "I");
2499  3 } else if (ck == long.class) {
2500  1 clz = Class.forName(prefix + "J");
2501  2 } else if (ck == float.class) {
2502  1 clz = Class.forName(prefix + "F");
2503  1 } else if (ck == double.class) {
2504  1 clz = Class.forName(prefix + "D");
2505    }
2506    } catch (ClassNotFoundException e) {
2507    }
2508    }
2509    }
2510   
2511  9 return clz;
2512    }
2513   
 
2514  170 toggle @SuppressWarnings({"rawtypes", "unchecked"})
2515    public static Collection createCollection(Type type) {
2516  170 Class<?> rawClass = getRawClass(type);
2517  170 Collection list;
2518  170 if(rawClass == AbstractCollection.class //
2519    || rawClass == Collection.class){
2520  18 list = new ArrayList();
2521  152 } else if(rawClass.isAssignableFrom(HashSet.class)){
2522  27 list = new HashSet();
2523  125 } else if(rawClass.isAssignableFrom(LinkedHashSet.class)){
2524  2 list = new LinkedHashSet();
2525  123 } else if(rawClass.isAssignableFrom(TreeSet.class)){
2526  17 list = new TreeSet();
2527  106 } else if(rawClass.isAssignableFrom(ArrayList.class)){
2528  85 list = new ArrayList();
2529  21 } else if(rawClass.isAssignableFrom(EnumSet.class)){
2530  2 Type itemType;
2531  2 if(type instanceof ParameterizedType){
2532  2 itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
2533    } else{
2534  0 itemType = Object.class;
2535    }
2536  2 list = EnumSet.noneOf((Class<Enum>) itemType);
2537  19 } else if(rawClass.isAssignableFrom(Queue.class)){
2538  1 list = new LinkedList();
2539    } else{
2540  18 try{
2541  18 list = (Collection) rawClass.newInstance();
2542    } catch(Exception e){
2543  5 throw new JSONException("create instance error, class " + rawClass.getName());
2544    }
2545    }
2546  165 return list;
2547    }
2548   
 
2549  2285 toggle public static Class<?> getRawClass(Type type){
2550  2285 if(type instanceof Class<?>){
2551  1213 return (Class<?>) type;
2552  1072 } else if(type instanceof ParameterizedType){
2553  1072 return getRawClass(((ParameterizedType) type).getRawType());
2554    } else{
2555  0 throw new JSONException("TODO");
2556    }
2557    }
2558   
 
2559  1748 toggle public static boolean isProxy(Class<?> clazz){
2560  1748 for(Class<?> item : clazz.getInterfaces()){
2561  159 String interfaceName = item.getName();
2562  159 if(interfaceName.equals("net.sf.cglib.proxy.Factory") //
2563    || interfaceName.equals("org.springframework.cglib.proxy.Factory")){
2564  1 return true;
2565    }
2566  158 if(interfaceName.equals("javassist.util.proxy.ProxyObject") //
2567    || interfaceName.equals("org.apache.ibatis.javassist.util.proxy.ProxyObject")
2568    ){
2569  1 return true;
2570    }
2571  157 if (interfaceName.equals("org.hibernate.proxy.HibernateProxy")) {
2572  0 return true;
2573    }
2574    }
2575  1747 return false;
2576    }
2577   
 
2578  16558 toggle public static boolean isTransient(Method method){
2579  16556 if(method == null){
2580  8725 return false;
2581    }
2582  7831 if(!transientClassInited){
2583  1 try{
2584  1 transientClass = (Class<? extends Annotation>) Class.forName("java.beans.Transient");
2585    } catch(Exception e){
2586    // skip
2587    } finally{
2588  1 transientClassInited = true;
2589    }
2590    }
2591  7832 if(transientClass != null){
2592  7833 Annotation annotation = TypeUtils.getAnnotation(method, transientClass);
2593  7831 return annotation != null;
2594    }
2595  0 return false;
2596    }
2597   
 
2598  10629 toggle public static boolean isAnnotationPresentOneToMany(Method method) {
2599  10629 if (method == null) {
2600  7217 return false;
2601    }
2602   
2603  3414 if (class_OneToMany == null && !class_OneToMany_error) {
2604  1 try {
2605  1 class_OneToMany = (Class<? extends Annotation>) Class.forName("javax.persistence.OneToMany");
2606    } catch (Throwable e) {
2607    // skip
2608  0 class_OneToMany_error = true;
2609    }
2610    }
2611  3413 return class_OneToMany != null && method.isAnnotationPresent(class_OneToMany);
2612   
2613    }
2614   
 
2615  10630 toggle public static boolean isAnnotationPresentManyToMany(Method method) {
2616  10628 if (method == null) {
2617  7217 return false;
2618    }
2619   
2620  3411 if (class_ManyToMany == null && !class_ManyToMany_error) {
2621  1 try {
2622  1 class_ManyToMany = (Class<? extends Annotation>) Class.forName("javax.persistence.ManyToMany");
2623    } catch (Throwable e) {
2624    // skip
2625  0 class_ManyToMany_error = true;
2626    }
2627    }
2628  3410 return class_ManyToMany != null && (method.isAnnotationPresent(class_OneToMany) || method.isAnnotationPresent(class_ManyToMany));
2629   
2630    }
2631   
 
2632  1 toggle public static boolean isHibernateInitialized(Object object){
2633  1 if(object == null){
2634  0 return false;
2635    }
2636  1 if(method_HibernateIsInitialized == null && !method_HibernateIsInitialized_error){
2637  1 try{
2638  1 Class<?> class_Hibernate = Class.forName("org.hibernate.Hibernate");
2639  1 method_HibernateIsInitialized = class_Hibernate.getMethod("isInitialized", Object.class);
2640    } catch(Throwable e){
2641    // skip
2642  0 method_HibernateIsInitialized_error = true;
2643    }
2644    }
2645  1 if(method_HibernateIsInitialized != null){
2646  1 try{
2647  1 Boolean initialized = (Boolean) method_HibernateIsInitialized.invoke(null, object);
2648  1 return initialized.booleanValue();
2649    } catch(Throwable e){
2650    // skip
2651    }
2652    }
2653  0 return true;
2654    }
2655   
 
2656  5000032 toggle public static double parseDouble(String str) {
2657  5000032 final int len = str.length();
2658  5000032 if (len > 10) {
2659  2330571 return Double.parseDouble(str);
2660    }
2661   
2662  2669461 boolean negative = false;
2663   
2664  2669461 long longValue = 0;
2665  2669461 int scale = 0;
2666  27526315 for (int i = 0; i < len; ++i) {
2667  24856881 char ch = str.charAt(i);
2668  24856881 if (ch == '-' && i == 0) {
2669  232868 negative = true;
2670  232868 continue;
2671    }
2672   
2673  24624013 if (ch == '.') {
2674  937226 if (scale != 0) {
2675  0 return Double.parseDouble(str);
2676    }
2677  937226 scale = len - i - 1;
2678  937226 continue;
2679    }
2680   
2681  23686787 if (ch >= '0' && ch <= '9') {
2682  23686760 int digit = ch - '0';
2683  23686760 longValue = longValue * 10 + digit;
2684    } else {
2685  27 return Double.parseDouble(str);
2686    }
2687    }
2688   
2689  2669434 if (negative) {
2690  232868 longValue = -longValue;
2691    }
2692   
2693  2669434 switch (scale) {
2694  1732235 case 0:
2695  1732235 return (double) longValue;
2696  10 case 1:
2697  10 return ((double) longValue) / 10;
2698  3 case 2:
2699  3 return ((double) longValue) / 100;
2700  44 case 3:
2701  44 return ((double) longValue) / 1000;
2702  357 case 4:
2703  357 return ((double) longValue) / 10000;
2704  3542 case 5:
2705  3542 return ((double) longValue) / 100000;
2706  35779 case 6:
2707  35779 return ((double) longValue) / 1000000;
2708  358155 case 7:
2709  358155 return ((double) longValue) / 10000000;
2710  539309 case 8:
2711  539309 return ((double) longValue) / 100000000;
2712  0 case 9:
2713  0 return ((double) longValue) / 1000000000;
2714    }
2715   
2716  0 return Double.parseDouble(str);
2717    }
2718   
 
2719  4000032 toggle public static float parseFloat(String str) {
2720  4000032 final int len = str.length();
2721  4000032 if (len >= 10) {
2722  2347279 return Float.parseFloat(str);
2723    }
2724   
2725  1652753 boolean negative = false;
2726   
2727  1652753 long longValue = 0;
2728  1652753 int scale = 0;
2729  16343331 for (int i = 0; i < len; ++i) {
2730  14690583 char ch = str.charAt(i);
2731  14690583 if (ch == '-' && i == 0) {
2732  23195 negative = true;
2733  23195 continue;
2734    }
2735   
2736  14667388 if (ch == '.') {
2737  396435 if (scale != 0) {
2738  0 return Float.parseFloat(str);
2739    }
2740  396435 scale = len - i - 1;
2741  396435 continue;
2742    }
2743   
2744  14270953 if (ch >= '0' && ch <= '9') {
2745  14270948 int digit = ch - '0';
2746  14270948 longValue = longValue * 10 + digit;
2747    } else {
2748  5 return Float.parseFloat(str);
2749    }
2750    }
2751   
2752  1652748 if (negative) {
2753  23195 longValue = -longValue;
2754    }
2755   
2756  1652748 switch (scale) {
2757  1256318 case 0:
2758  1256318 return (float) longValue;
2759  9 case 1:
2760  9 return ((float) longValue) / 10;
2761  1 case 2:
2762  1 return ((float) longValue) / 100;
2763  34 case 3:
2764  34 return ((float) longValue) / 1000;
2765  368 case 4:
2766  368 return ((float) longValue) / 10000;
2767  3550 case 5:
2768  3550 return ((float) longValue) / 100000;
2769  35490 case 6:
2770  35490 return ((float) longValue) / 1000000;
2771  356978 case 7:
2772  356978 return ((float) longValue) / 10000000;
2773  0 case 8:
2774  0 return ((float) longValue) / 100000000;
2775  0 case 9:
2776  0 return ((float) longValue) / 1000000000;
2777    }
2778   
2779  0 return Float.parseFloat(str);
2780    }
2781   
 
2782  447 toggle public static long fnv1a_64_lower(String key){
2783  447 long hashCode = 0xcbf29ce484222325L;
2784  3235 for(int i = 0; i < key.length(); ++i){
2785  2788 char ch = key.charAt(i);
2786  2788 if(ch == '_' || ch == '-'){
2787  44 continue;
2788    }
2789  2744 if(ch >= 'A' && ch <= 'Z'){
2790  183 ch = (char) (ch + 32);
2791    }
2792  2744 hashCode ^= ch;
2793  2744 hashCode *= 0x100000001b3L;
2794    }
2795  447 return hashCode;
2796    }
2797   
 
2798  4419 toggle public static long fnv1a_64(String key){
2799  4421 long hashCode = 0xcbf29ce484222325L;
2800  103371 for(int i = 0; i < key.length(); ++i){
2801  98967 char ch = key.charAt(i);
2802  98924 hashCode ^= ch;
2803  98940 hashCode *= 0x100000001b3L;
2804    }
2805  4423 return hashCode;
2806    }
2807   
 
2808  4444 toggle public static boolean isKotlin(Class clazz) {
2809  4444 if (kotlin_metadata == null && !kotlin_metadata_error) {
2810  1 try {
2811  1 kotlin_metadata = Class.forName("kotlin.Metadata");
2812    } catch (Throwable e) {
2813  0 kotlin_metadata_error = true;
2814    }
2815    }
2816  4444 return kotlin_metadata != null && clazz.isAnnotationPresent(kotlin_metadata);
2817    }
2818   
 
2819  20 toggle public static Constructor getKoltinConstructor(Constructor[] constructors){
2820  20 return getKoltinConstructor(constructors, null);
2821    }
2822   
 
2823  39 toggle public static Constructor getKoltinConstructor(Constructor[] constructors, String[] paramNames){
2824  39 Constructor creatorConstructor = null;
2825  39 for(Constructor<?> constructor : constructors){
2826  67 Class<?>[] parameterTypes = constructor.getParameterTypes();
2827  67 if (paramNames != null && parameterTypes.length != paramNames.length) {
2828  13 continue;
2829    }
2830   
2831  54 if(parameterTypes.length > 0 && parameterTypes[parameterTypes.length - 1].getName().equals("kotlin.jvm.internal.DefaultConstructorMarker")){
2832  6 continue;
2833    }
2834  48 if(creatorConstructor != null && creatorConstructor.getParameterTypes().length >= parameterTypes.length){
2835  3 continue;
2836    }
2837  45 creatorConstructor = constructor;
2838    }
2839  39 return creatorConstructor;
2840    }
2841   
 
2842  66 toggle public static String[] getKoltinConstructorParameters(Class clazz){
2843  66 if(kotlin_kclass_constructor == null && !kotlin_class_klass_error){
2844  1 try{
2845  1 Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
2846  1 kotlin_kclass_constructor = class_kotlin_kclass.getConstructor(Class.class);
2847    } catch(Throwable e){
2848  0 kotlin_class_klass_error = true;
2849    }
2850    }
2851  66 if (kotlin_kclass_constructor == null){
2852  0 return null;
2853    }
2854   
2855  66 if (kotlin_kclass_getConstructors == null && !kotlin_class_klass_error) {
2856  1 try{
2857  1 Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
2858  1 kotlin_kclass_getConstructors = class_kotlin_kclass.getMethod("getConstructors");
2859    } catch(Throwable e){
2860  0 kotlin_class_klass_error = true;
2861    }
2862    }
2863   
2864  66 if (kotlin_kfunction_getParameters == null && !kotlin_class_klass_error) {
2865  1 try{
2866  1 Class class_kotlin_kfunction = Class.forName("kotlin.reflect.KFunction");
2867  1 kotlin_kfunction_getParameters = class_kotlin_kfunction.getMethod("getParameters");
2868    } catch(Throwable e){
2869  0 kotlin_class_klass_error = true;
2870    }
2871    }
2872   
2873  66 if (kotlin_kparameter_getName == null && !kotlin_class_klass_error) {
2874  1 try{
2875  1 Class class_kotlinn_kparameter = Class.forName("kotlin.reflect.KParameter");
2876  1 kotlin_kparameter_getName = class_kotlinn_kparameter.getMethod("getName");
2877    } catch(Throwable e){
2878  0 kotlin_class_klass_error = true;
2879    }
2880    }
2881   
2882  66 if (kotlin_error){
2883  0 return null;
2884    }
2885   
2886  66 try{
2887  66 Object constructor = null;
2888  66 Object kclassImpl = kotlin_kclass_constructor.newInstance(clazz);
2889  66 Iterable it = (Iterable) kotlin_kclass_getConstructors.invoke(kclassImpl);
2890  141 for(Iterator iterator = it.iterator(); iterator.hasNext(); iterator.hasNext()){
2891  75 Object item = iterator.next();
2892  75 List parameters = (List) kotlin_kfunction_getParameters.invoke(item);
2893  75 if (constructor != null && parameters.size() == 0) {
2894  6 continue;
2895    }
2896  69 constructor = item;
2897    }
2898  66 List parameters = (List) kotlin_kfunction_getParameters.invoke(constructor);
2899  66 String[] names = new String[parameters.size()];
2900  239 for(int i = 0; i < parameters.size(); i++){
2901  173 Object param = parameters.get(i);
2902  173 names[i] = (String) kotlin_kparameter_getName.invoke(param);
2903    }
2904  66 return names;
2905    } catch(Throwable e){
2906  0 e.printStackTrace();
2907  0 kotlin_error = true;
2908    }
2909  0 return null;
2910    }
2911   
 
2912  168 toggle private static boolean isKotlinIgnore(Class clazz, String methodName) {
2913  168 if (kotlinIgnores == null && !kotlinIgnores_error) {
2914  1 try {
2915  1 Map<Class, String[]> map = new HashMap<Class, String[]>();
2916  1 Class charRangeClass = Class.forName("kotlin.ranges.CharRange");
2917  1 map.put(charRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2918  1 Class intRangeClass = Class.forName("kotlin.ranges.IntRange");
2919  1 map.put(intRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2920  1 Class longRangeClass = Class.forName("kotlin.ranges.LongRange");
2921  1 map.put(longRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2922  1 Class floatRangeClass = Class.forName("kotlin.ranges.ClosedFloatRange");
2923  1 map.put(floatRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2924  1 Class doubleRangeClass = Class.forName("kotlin.ranges.ClosedDoubleRange");
2925  1 map.put(doubleRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2926  1 kotlinIgnores = map;
2927    } catch (Throwable error) {
2928  0 kotlinIgnores_error = true;
2929    }
2930    }
2931  168 if (kotlinIgnores == null) {
2932  0 return false;
2933    }
2934  168 String[] ignores = kotlinIgnores.get(clazz);
2935  168 return ignores != null && Arrays.binarySearch(ignores, methodName) >= 0;
2936    }
2937   
 
2938  18308 toggle public static <A extends Annotation> A getAnnotation(Class<?> targetClass, Class<A> annotationClass){
2939  18309 A targetAnnotation = targetClass.getAnnotation(annotationClass);
2940   
2941  18313 Class<?> mixInClass = null;
2942  18312 Type type = JSON.getMixInAnnotations(targetClass);
2943  18312 if (type instanceof Class<?>) {
2944  62 mixInClass = (Class<?>) type;
2945    }
2946   
2947  18310 if(mixInClass != null) {
2948  62 A mixInAnnotation = mixInClass.getAnnotation(annotationClass);
2949  62 if(mixInAnnotation == null && mixInClass.getAnnotations().length > 0){
2950  0 for(Annotation annotation : mixInClass.getAnnotations()){
2951  0 mixInAnnotation = annotation.annotationType().getAnnotation(annotationClass);
2952  0 if(mixInAnnotation != null){
2953  0 break;
2954    }
2955    }
2956    }
2957  62 if (mixInAnnotation != null) {
2958  28 return mixInAnnotation;
2959    }
2960    }
2961   
2962  18282 if(targetAnnotation == null && targetClass.getAnnotations().length > 0){
2963  279 for(Annotation annotation : targetClass.getAnnotations()){
2964  293 targetAnnotation = annotation.annotationType().getAnnotation(annotationClass);
2965  293 if(targetAnnotation != null){
2966  0 break;
2967    }
2968    }
2969    }
2970  18283 return targetAnnotation;
2971    }
2972   
 
2973  17341 toggle public static <A extends Annotation> A getAnnotation(Field field, Class<A> annotationClass){
2974  17341 A targetAnnotation = field.getAnnotation(annotationClass);
2975   
2976  17343 Class<?> clazz = field.getDeclaringClass();
2977  17343 A mixInAnnotation;
2978  17343 Class<?> mixInClass = null;
2979  17343 Type type = JSON.getMixInAnnotations(clazz);
2980  17343 if (type instanceof Class<?>) {
2981  29 mixInClass = (Class<?>) type;
2982    }
2983   
2984  17343 if (mixInClass != null) {
2985  29 Field mixInField = null;
2986  29 String fieldName = field.getName();
2987    // 递归从MixIn类的父类中查找注解(如果有父类的话)
2988  44 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
2989    currClass = currClass.getSuperclass()) {
2990  35 try {
2991  35 mixInField = currClass.getDeclaredField(fieldName);
2992  20 break;
2993    } catch (NoSuchFieldException e) {
2994    // skip
2995    }
2996    }
2997  29 if (mixInField == null) {
2998  9 return targetAnnotation;
2999    }
3000  20 mixInAnnotation = mixInField.getAnnotation(annotationClass);
3001  20 if (mixInAnnotation != null) {
3002  20 return mixInAnnotation;
3003    }
3004    }
3005  17313 return targetAnnotation;
3006    }
3007   
 
3008  21592 toggle public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationClass){
3009  21592 A targetAnnotation = method.getAnnotation(annotationClass);
3010   
3011  21593 Class<?> clazz = method.getDeclaringClass();
3012  21592 A mixInAnnotation;
3013  21592 Class<?> mixInClass = null;
3014  21591 Type type = JSON.getMixInAnnotations(clazz);
3015  21589 if (type instanceof Class<?>) {
3016  35 mixInClass = (Class<?>) type;
3017    }
3018   
3019  21586 if (mixInClass != null) {
3020  35 Method mixInMethod = null;
3021  35 String methodName = method.getName();
3022  35 Class<?>[] parameterTypes = method.getParameterTypes();
3023    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3024  62 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3025    currClass = currClass.getSuperclass()) {
3026  37 try {
3027  37 mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes);
3028  10 break;
3029    } catch (NoSuchMethodException e) {
3030    // skip
3031    }
3032    }
3033  35 if (mixInMethod == null) {
3034  25 return targetAnnotation;
3035    }
3036  10 mixInAnnotation = mixInMethod.getAnnotation(annotationClass);
3037  10 if (mixInAnnotation != null) {
3038  4 return mixInAnnotation;
3039    }
3040    }
3041  21556 return targetAnnotation;
3042    }
3043   
 
3044  22 toggle public static Annotation[][] getParameterAnnotations(Method method){
3045  22 Annotation[][] targetAnnotations = method.getParameterAnnotations();
3046   
3047  22 Class<?> clazz = method.getDeclaringClass();
3048  22 Annotation[][] mixInAnnotations;
3049  22 Class<?> mixInClass = null;
3050  22 Type type = JSON.getMixInAnnotations(clazz);
3051  22 if (type instanceof Class<?>) {
3052  0 mixInClass = (Class<?>) type;
3053    }
3054   
3055  22 if (mixInClass != null) {
3056  0 Method mixInMethod = null;
3057  0 String methodName = method.getName();
3058  0 Class<?>[] parameterTypes = method.getParameterTypes();
3059    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3060  0 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3061    currClass = currClass.getSuperclass()) {
3062  0 try {
3063  0 mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes);
3064  0 break;
3065    } catch (NoSuchMethodException e) {
3066  0 continue;
3067    }
3068    }
3069  0 if (mixInMethod == null) {
3070  0 return targetAnnotations;
3071    }
3072  0 mixInAnnotations = mixInMethod.getParameterAnnotations();
3073  0 if (mixInAnnotations != null) {
3074  0 return mixInAnnotations;
3075    }
3076    }
3077  22 return targetAnnotations;
3078    }
3079   
 
3080  403 toggle public static Annotation[][] getParameterAnnotations(Constructor constructor){
3081  403 Annotation[][] targetAnnotations = constructor.getParameterAnnotations();
3082   
3083  403 Class<?> clazz = constructor.getDeclaringClass();
3084  403 Annotation[][] mixInAnnotations;
3085  403 Class<?> mixInClass = null;
3086  403 Type type = JSON.getMixInAnnotations(clazz);
3087  403 if (type instanceof Class<?>) {
3088  3 mixInClass = (Class<?>) type;
3089    }
3090   
3091  403 if (mixInClass != null) {
3092  3 Constructor mixInConstructor = null;
3093  3 Class<?>[] parameterTypes = constructor.getParameterTypes();
3094    // 构建参数列表,因为内部类的构造函数需要传入外部类的引用
3095  3 List<Class<?>> enclosingClasses = new ArrayList<Class<?>>(2);
3096  6 for (Class<?> enclosingClass = mixInClass.getEnclosingClass(); enclosingClass != null; enclosingClass = enclosingClass.getEnclosingClass()) {
3097  3 enclosingClasses.add(enclosingClass);
3098    }
3099  3 int level = enclosingClasses.size();
3100    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3101  3 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3102    currClass = currClass.getSuperclass()) {
3103  3 try {
3104  3 if (level != 0) {
3105  3 Class<?>[] outerClassAndParameterTypes = new Class[level + parameterTypes.length];
3106  3 System.arraycopy(parameterTypes, 0, outerClassAndParameterTypes, level, parameterTypes.length);
3107  6 for (int i = level; i > 0 ; i--) {
3108  3 outerClassAndParameterTypes[i - 1] = enclosingClasses.get(i - 1);
3109    }
3110  3 mixInConstructor = mixInClass.getDeclaredConstructor(outerClassAndParameterTypes);
3111    } else {
3112  0 mixInConstructor = mixInClass.getDeclaredConstructor(parameterTypes);
3113    }
3114  3 break;
3115    } catch (NoSuchMethodException e) {
3116  0 level--;
3117    }
3118    }
3119  3 if (mixInConstructor == null) {
3120  0 return targetAnnotations;
3121    }
3122  3 mixInAnnotations = mixInConstructor.getParameterAnnotations();
3123  3 if (mixInAnnotations != null) {
3124  3 return mixInAnnotations;
3125    }
3126    }
3127  400 return targetAnnotations;
3128    }
3129   
 
3130  24 toggle public static boolean isJacksonCreator(Method method) {
3131  24 if (method == null) {
3132  0 return false;
3133    }
3134   
3135  24 if (class_JacksonCreator == null && !class_JacksonCreator_error) {
3136  1 try {
3137  1 class_JacksonCreator = (Class<? extends Annotation>) Class.forName("com.fasterxml.jackson.annotation.JsonCreator");
3138    } catch (Throwable e) {
3139    // skip
3140  0 class_JacksonCreator_error = true;
3141    }
3142    }
3143  24 return class_JacksonCreator != null && method.isAnnotationPresent(class_JacksonCreator);
3144    }
3145    }